Ограничение доступа к контроллеру Spring MVC - N сеансов за раз

Мы лицензировали коммерческий продукт (продукт не важен в данном контексте), который ограничен количеством одновременных пользователей. Пользователи получают доступ к этому продукту через Spring Controller.

У нас есть N лицензий на этот продукт, и если к нему обращаются N + 1 пользователей, они получают неприятное сообщение об ошибке о необходимости покупки дополнительных лицензий. Я хочу убедиться, что пользователи не видят это сообщение, и предпочел бы, чтобы запросы к продукту просто «стояли в очереди», а не имели к нему доступ N + 1 пользователей. Конечно, они предпочли бы, чтобы я купил лицензии, поэтому их инструмент не позволяет нам делать это изначально.

Вместо возможности управлять инструментом я хотел бы ограничить количество одновременных сеансов с контроллером, чтобы они никогда не превышали N. Все остальные могут подождать.

Мы используем Spring MVC.

Любые идеи?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
6
0
2 494
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Что вам нужно, так это ObjectPool. Проверьте пул Apache Commons http://commons.apache.org/pool

При запуске приложения вы должны создать пул объектов с лицензиями или объектами коммерческой библиотеки (не уверен, какой у них публичный интерфейс).

public class CommercialObjectFactory extends BasePoolableObjectFactory { 
    // for makeObject we'll simply return a new commercial object
    @Override
    public Object makeObject() { 
        return new CommercialObject(); 
    } 
}

GenericObjectPool pool = new GenericObjectPool(new CommercialObjectFactory());

// The size of pool in our case it is N
pool.setMaxActive(N) 
// We want to wait if the pool is exhausted
pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_BLOCK) 

И когда вам понадобится коммерческий объект в вашем коде.

CommercialObject obj = null;
try { 
    obj = (CommercialObject)pool.borrowObject();

    // use the commerical object the way you to use it.
    // ....

} finally { 
    // be nice return the borrwed object
    try {
        if (obj != null) {
            pool.returnObject(obj);
        }
    } catch(Exception e) {
        // ignored
    }
} 

Если это не то, что вам нужно, вам нужно будет предоставить более подробную информацию о вашей коммерческой библиотеке.

Я думаю о SessionListener, чтобы увеличивать счетчик при создании сеанса и уменьшать его, когда сеанс недействителен или истекает время ожидания, и аспект для защиты вызовов к URL-адресу. Но дизайн, который явно сочетает в себе две идеи, ускользает от меня.

Spring имеет org.springframework.aop.interceptor.ConcurrencyThrottleInterceptor, который можно использовать через АОП (или базовый код может использоваться автономно). Это может быть более легкий подход, чем использование пула объектов.

Другие вопросы по теме