17

我正在使用 Spring 3 + Spring MVC 开发一个简单的 REST API。身份验证将通过 OAuth 2.0 或使用 Spring Security 的带有客户端令牌的基本身份验证来完成。这仍在辩论中。所有连接都将强制通过 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 秒内使用它发出了多少请求。这将允许我们为不同的客户做一些事情,比如不同的速率限制。

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

4

6 回答 6

1

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

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

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

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

于 2019-04-01T02:40:37.497 回答
0

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

我查看了HAProxy LB 文档,那里没有什么太明显的地方,但是这个要求可能需要对 ACL 进行全面调查。

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

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

我希望这有帮助。抢

于 2012-04-17T00:56:41.540 回答
0

您可以在流程中的各个点设置速率限制(通常越高越好),您所采用的一般方法很有意义。实现的一种选择是使用 3scale 来完成它(http://www.3scale.net) - 它执行速率限制、分析、密钥管理等,并且可以与代码插件一起使用(Java 插件在这里:https ://github.com/3scale/3scale_ws_api_for_java),它推动或通过将 Varnish(http://www.varnish-cache.org)之类的东西放入管道中并具有应用速率限制。

于 2012-06-06T11:00:33.967 回答
0

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

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

于 2015-12-11T06:39:34.947 回答
0

我们使用 redis 作为漏桶后端

添加控制器作为入口

谷歌将该令牌缓存为具有过期时间的键

然后过滤每个请求

于 2018-04-06T06:10:20.437 回答
-1

最好使用 REDIS 实现ratelimit。有关更多信息,请查看此速率限制 js 示例。

于 2013-12-31T11:59:10.007 回答