java 如何在Spring中實現基於客戶端令牌的速率限制?




spring security google oauth2 (4)

我正在使用Spring 3 + Spring MVC開發一個簡單的REST API。 身份驗證將通過使用Spring Security的客戶端令牌通過OAuth 2.0或基本身份驗證完成。 這仍在爭論中。 所有連接將通過SSL連接強制。

我一直在尋找有關如何實施速率限制的信息,但似乎並沒有很多信息。 實現需要分佈,因為它可以在多個Web服務器上工作。

例如,如果有三台api服務器A,B,C和客戶端每秒被限制為5個請求,則發出如此請求的6個請求的客戶端將發現拒絕服務的請求發生錯誤。

A recieves 3 requests   \
B receives 2 requests    | Executed in order, all requests from one client.
C receives 1 request    /

它需要基於包含在請求中的令牌來工作 ,因為一個客戶端可能代表許多用戶發出請求,並且每個用戶應該受到速率限制,而不是服務器IP地址。

HAProxy負載平衡器後面將安裝多個(2-5)Web服務器。 有一個Cassandra支持,使用memcached。 Web服務器將在Jetty上運行。

一個可能的解決方案可能是編寫一個自定義的Spring Security過濾器來提取令牌,並檢查在最近X秒內有多少請求。 這樣可以讓我們為不同的客戶做一些不同的費率限制。

有關如何完成的任何建議? 有沒有現有的解決方案,還是我必須寫我自己的解決方案? 以前我沒有做過很多的網站基礎設施。



Answer #2

如果可能的話,我會避免修改應用程序級代碼來滿足這個要求。

我看了一下HAProxy LB的文檔,這裡沒有太明顯的地方,但是這個要求可能需要對ACL進行全面的調查。

把HAProxy放在一邊,一個可能的架構就是放一個Apache WebServer,並使用Apache插件來限制速度。 超出限制的請求將被拒絕,而Apache後面的層中的應用程序服務器將與速率限制問題分離開來,從而使其更簡單。 您也可以考慮從Web服務器提供靜態內容。

請參閱此問題的答案如何使用Apache實現速率限制? (每秒請求)

我希望這有幫助。 搶


Answer #3

您可以在流量中的各個點(通常是越高越好)提供流量限制,而且您所採用的一般方法很有意義。 實施的一個選擇是使用3scale來做到這一點( http://www.3scale.net ) - 它的速度限制,分析,密鑰管理等,並與代碼插件(Java插件在這裡: https ://github.com/3scale/3scale_ws_api_for_java )推動或通過像Varnish(http://www.varnish-cache.org)在管道中,並適用率限制。


Answer #4

幾天前我也在想同樣的解決方案。 基本上,我更喜歡“中央控制”解決方案來保存分佈式環境中客戶端請求的狀態。

在我的應用程序中,我使用“session_id”來標識請求客戶端。 然後創建一個servlet過濾器或者彈簧HandlerInterceptorAdapter來過濾請求,然後用中央控制的數據倉庫(可以是memcached,redis,cassandra或zookeeper)檢查“session_id”。







rate-limiting