我使用 HaProxy 实现了简单的速率限制,其方式与 StackExchange 使用 HaProxy 的方式类似。我试图让它更先进一点,以便有多个速率限制阈值。
例如,限制请求的客户端:
15/分钟
60/小时
360/天
似乎我需要多个棒表来存储具有不同采样率的相同数据。该文档指出:
每个代理只有一个stick-table。在编写本文档时,每个代理有多个表似乎没有用。如果碰巧需要这样做,只需创建一个虚拟后端并在其中引用它即可。
不幸的是,我有一段时间试图弄清楚如何将数据存储到虚拟后端表中。
我也对其他方法持开放态度,HaProxy 似乎是一条有前途的道路,因为我们已经在环境中拥有了它,所以它是有意义的。任何建议表示赞赏。
我只是想自己做这件事,运气不好,决定求助于我的 google-fu。在寻找多级速率限制时,对我来说最好的结果就是这个,我真的很兴奋。然后我看到它没有答案,最初陷入了绝望的生存深渊。在挖掘自己之后,我一直在破解,幸运的是,我似乎已经想出了如何做到这一点,至少可以满足我的需要。也许它也对你有用。
Haproxy 真的非常酷,我很高兴开始使用它来代替我们当前的负载平衡解决方案,但是 Stick-tables 有点让你头疼。在这方面,我发现了一个似乎对我有帮助的一般原则,那就是明确提及每一个当您尝试使用多个棍子表进行设置时,按名称粘贴表。默认行为,其中名称是隐式的(假设是您所在的后端),非常棒......除非您开始尝试使用多个棍子表。所以这就是为什么在我下面的配置中,其中一些比它必须的更冗长。我只是发现这样更容易遵循逻辑。无论如何,这里是(请注意,这是基于 Moodle 应用程序的 cookie,而不是 IP,并且它使用 v1.5.11 的 haproxy):
所以,这样做是设置一个计数器记录每 10 秒的速率,另一个记录每 60 秒的速率。请注意,它实际上并没有使用这些计数器来进行任何速率限制。但您可以通过以下方式进行验证:
费率计数器是单独维护的。
我想找出让这些计数器实际递增所需的最小配置,这就是为什么您在“tcp-request content reject”语句的末尾看到“FALSE”的原因。仅使用计数器定义 acl 不会使它们增加。你必须实际使用acl。将“FALSE”放在最后只是允许我使用 acl,而无需满足实际拒绝请求的条件。一旦我为这些 acl 确定了一些真正的数字,我可能会删除“FALSE”。
让多个 Stick 表工作的真正关键似乎是在您实际处理请求的后端。将其中任何一个移动到 dynamic_60 后端会导致该计数停止工作。我想原因是跟踪或应用 acls 到不服务请求的后端是没有意义的,因为它实际上并没有请求从中提取信息。也就是说,我相信其他人会有更好的解释。我对 haproxy 很陌生。
我问的下一个问题是:我是否仅限于跟踪 3 件事(因为“track-sc”配置设置仅从 0 到 2)。我相信,是的,您只能跟踪三件事。但重要的是,每人有 3 件事实际服务请求的后端。因此,例如,如果像我一样,您想对静态内容和动态内容进行不同的速率限制,您可以根据要求。然后在“static”后端,在“static”和“static_60”后端定义 track-sc0 和 track-sc1(如果您碰巧遵循与我上面放置的配置类似的命名方案)。然后,您将有 4 个表格用于做出限速决定。动态和静态内容的 10 秒和 60 秒速率。使用第三个计数器,我认为您可以进入 3 个级别,但我认为这将是极限。
我也修补了这个问题一段时间。David Ackerman 的解决方案运行良好,但如果您只需要两个限制,则可以使用第二个通用寄存器(自 HAProxy 1.9+ 起可用)来简化它。这是我限制每分钟和每天请求的解决方案。
此解决方案也不计算被阻止的请求