繁体   English   中英

如何在Spring中基于客户端令牌实现速率限制?

[英]How to implement rate limiting based on a client token in Spring?

我正在使用Spring 3 + Spring MVC开发一个简单的REST API。 使用Spring Security通过OAuth 2.0或基本身份验证与客户端令牌进行身份验证。 这仍然存在争议。 将强制所有连接通过SSL连接。

我一直在寻找有关如何实现速率限制的信息,但似乎并没有很多信息。 实现需要分发,因为它适用于多个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秒内使用它进行了多少次请求。 这将允许我们为不同的客户做一些不同的速率限制。

有关如何做到的任何建议? 有现成的解决方案还是我必须编写自己的解决方案? 我以前没有做过很多网站基础设施。

它需要基于请求中包含的令牌工作,因为一个客户端可能代表许多用户发出请求,并且每个用户应该是速率限制而不是服务器IP地址。

设置将是HAProxy负载均衡器后面的多个(2-5)Web服务器。 有一个Cassandra支持,并使用memcached。 Web服务器将在Jetty上运行。

我认为该项目是请求/响应http(s)协议。 你使用HAProxy作为前端。 也许HAProxy可以使用token进行负载均衡,您可以从这里查看

然后相同的token请求将到达相同的Web服务器,并且Web服务器可以只使用内存缓存来实现速率限制器。

如果可能的话,我会避免修改应用程序级代码以满足此要求。

我查看了HAProxy LB文档,没有太明显的,但是要求可能需要对ACL进行全面调查。

将HAProxy放在一边,可能的架构是将Apache WebServer放在前面并使用Apache插件来进行速率限制。 超出限制的请求在前面被拒绝,然后Apache之后的层中的应用程序服务器与速率限制问题分开,使它们变得更简单。 您还可以考虑从Web服务器提供静态内容。

查看此问题的答案如何使用Apache实现速率限制? (每秒请求数)

我希望这有帮助。

您可以将流量限制放在流量的不同点(通常越高越好),并且您采用的一般方法很有意义。 实现的一个选项是使用3scale( http://www.3scale.net ) - 它确实对速率限制,分析,密钥管理等进行操作,并且可以使用代码插件(Java插件在这里: https) ://github.com/3scale/3scale_ws_api_for_java )推送或通过将类似Varnish(http://www.varnish-cache.org)的东西推入管道并应用速率限制。

几天前我也在考虑类似的解决方案。 基本上,我更喜欢“中央控制”解决方案,以在分布式环境中保存客户端请求的状态。

在我的应用程序中,我使用“session_id”来标识请求客户端。 然后创建一个servlet过滤器或Spring HandlerInterceptorAdapter来过滤请求,然后使用中央控制的数据存储库检查“session_id”,该存储库可以是memcached,redis,cassandra或zookeeper。

我们使用redis作为漏桶后端

添加控制器作为入口

google将该令牌缓存为过期时间的密钥

然后过滤每个请求

最好使用REDIS实现ratelimit 有关详细信息,请查看此限制js示例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM