2008-12-21 31 views
6

我們已經獲得了一個商業產品(產品在此上下文中不重要)的許可,該產品受併發用戶數量的限制。用戶通過Spring Controller訪問該產品。限制對Spring MVC控制器的訪問 - 一次N個會話

我們有N個此產品的許可證,如果有N + 1個用戶訪問它,他們會收到關於需要購買更多許可證的令人討厭的錯誤消息。我想確保用戶看不到這條消息,並且希望對產品的請求只是「排隊」,而不是讓N + 1用戶實際訪問它。當然,他們更喜歡我購買許可證,所以他們的工具不會讓我們在本地執行此操作。

代替能夠控制工具,我想限制併發會話的數量,以控制器永遠不會超過N.其他人都可以等待。

我們使用Spring MVC。

任何想法?

回答

7

你需要的是一個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 
    } 
} 

如果這不是你想要的,那麼你將需要提供更多關於你的商業圖書館的細節。

0

我正在考慮SessionListener在創建會話時遞增計數,並在會話失效或超時時將其遞減,並監視對該URL的呼叫的方面。但是將這兩個想法明確地結合在一起的設計正在逃避我。

3

Spring有一個org.springframework.aop.interceptor.ConcurrencyThrottleInterceptor可以通過AOP使用(或底層代碼可以獨立使用)。這可能是一個比使用對象池更輕的方法。