6

我们已授权商业产品(在此上下文中不重要的产品),该产品受并发用户数量的限制。用户通过 Spring Controller 访问该产品。

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

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

我们正在使用 Spring MVC。

有任何想法吗?

4

3 回答 3

7

你需要的是一个对象池。查看 Apache Commons Pool 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
    }
} 

如果这不是您想要的,那么您将需要提供有关您的商业图书馆的更多详细信息。

于 2008-12-22T06:59:10.443 回答
3

Spring has a org.springframework.aop.interceptor.ConcurrencyThrottleInterceptor that can be used via AOP (or the underlying code can be used standalone). That might be a lighter weight approach than using a object pool.

于 2009-01-16T19:21:41.497 回答
0

我正在考虑使用 SessionListener 在创建会话时增加计数,并在会话无效或超时时减少计数,以及保护对 URL 的调用的方面。但是一个将这两个想法明显结合在一起的设计让我望而却步。

于 2008-12-26T23:22:55.040 回答