2012-04-16 33 views
12

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

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

例如,如果有三臺api服務器A,B,C和客戶端每秒限制爲5個請求,那麼發出6個請求的客戶端會發現請求C被拒絕並出現錯誤。

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秒內對它做了多少請求。這將允許我們爲不同的客戶做一些不同的費率限制。

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

+0

您正處於正確的軌道上,並且帶有過濾器的想法。既然你已經在使用memcached,它應該很簡單。 – sourcedelica 2012-04-17 03:45:30

+0

它看起來像一個過濾器可能是要走的路。找到一篇有用的文章,介紹如何實現一個桶系統的時間間隔,這樣你就可以檢查最近X分鐘/秒的使用情況 - > http://chris6f.com/rate-limiting-with-redis。它使用redis,但原理應該與memcache或cassandra類似。 – 2012-04-18 23:42:06

回答

0

我會盡可能避免修改應用程序級代碼以滿足此要求。

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

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

看到這個問題的答案How can I implement rate limiting with Apache? (requests per second)

我希望這有助於。 Rob

+1

感謝您的回答。該項目目前不使用Apache WebServer,Jetty用於部署war文件。現有的一些戰爭構成了當前的應用程序,而API將僅僅是在Jetty中運行的另一個Web應用程序。切換到Apache將是一個相當大的努力,所以我儘可能避免它。似乎Apache mods專注於IP而不是令牌限制。在應用程序代碼中做它是一種痛苦,但似乎提供了最大的控制。它可能很慢,但並不打算用於阻止DDoS攻擊。 – 2012-04-17 03:26:42

0

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

0

我前幾天還想到了類似的解決方案。基本上,我更喜歡「中央控制」解決方案來保存分佈式環境中客戶端請求的狀態。

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

相關問題