如何在春季基于客户端令牌实施速率限制?

我正在使用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。网络服务器将在Jetty上运行。

一种潜在的解决方案可能是编写一个自定义的Spring Security过滤器,用于提取令牌并检查在过去X秒内使用令牌发出了多少请求。这将使我们能够做一些事情,例如针对不同客户端的不同速率限制。

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


答案 1

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

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

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

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


答案 2

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

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

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

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

我希望这有帮助。抢


推荐