限制对Spring MVC控制器的访问 - 一次N个会话

问题描述:

我们已经获得了一个商业产品(产品在此上下文中不重要)的许可,该产品受并发用户数量的限制。用户通过Spring Controller访问该产品。限制对Spring MVC控制器的访问 - 一次N个会话

我们有N个此产品的许可证,如果有N + 1个用户访问它,他们会收到关于需要购买更多许可证的令人讨厌的错误消息。我想确保用户看不到这条消息,并且希望对产品的请求只是“排队”,而不是让N + 1用户实际访问它。当然,他们更喜欢我购买许可证,所以他们的工具不会让我们在本地执行此操作。

代替能够控制工具,我想限制并发会话的数量,以控制器永远不会超过N.其他人都可以等待。

我们使用Spring MVC。

任何想法?

你需要的是一个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可以通过AOP使用(或底层代码可以独立使用)。这可能是一个比使用对象池更轻的方法。