2012-04-16 34 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”。

相关问题