我在 Ubuntu 上使用 HAProxy 来执行一些速率限制。以下是我的配置中最重要的片段:
global
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
frontend http-listener
bind *:80 accept-proxy
http-request track-sc1 src table st_ip_req_rate
http-request deny deny_status 429 if { sc_http_req_rate(1) gt 100 }
http-request deny deny_status 429 if { sc_http_err_rate(1) gt 200 }
default_backend no-match-backend
backend st_ip_req_rate
stick-table type ip size 100k expire 24h store http_req_rate(10s),http_err_rate(24h)
backend no-match-backend
http-request deny deny_status 503
我没有在这里包含我的实际后端,但在这个例子中我的期望是:
- 请求通常会以状态 503 来回答
- 10 秒滑动窗口内的第 101 个请求的答复状态为 429
- 在 24 小时内的滑动窗口内,200 个请求之后的第一个请求回答了 4xx 状态代码回答状态为 429
我希望滑动窗口能够发挥作用,sc_http_req_rate
因为示例这篇博文也使用超过 10 秒的速率expire 30s
。但是,在 100 次请求之后,请求被拒绝,错误代码为 429。当我查看 stick 表时,如下所示:
$ echo "show table st_ip_req_rate" | sudo socat unix:/run/haproxy/admin.sock -
# table: st_ip_req_rate, type: ip, size:102400, used:10
0x7f133c01b8d8: key=192.1.2.3 use=0 exp=86389546 http_req_rate(10000)=639 http_err_rate(86400000)=0
...
我可以看到http_req_rate并没有下降。
我期望不同的行为是错误的吗?还是这是一个错误?我检查了下面的链接,当时(2021 年 3 月 25 日)似乎没有已知的错误匹配。
$ haproxy -v
HA-Proxy version 2.2.11-1ppa1~focal 2021/03/18 - https://haproxy.org/
Status: long-term supported branch - will stop receiving fixes around Q2 2025.
Known bugs: http://www.haproxy.org/bugs/bugs-2.2.11.html
Running on: Linux 5.4.0-67-generic #75-Ubuntu SMP Fri Feb 19 18:03:38 UTC 2021 x86_64
答案来自这个问题建议用于table_http_req_rate
类似问题。这不适用于此处,因为如果没有超过 10 秒的请求,我的请求率也不会下降。
答案1
我也遇到过这种情况。好像是回归。切换到 2.3.X(特别是 2.3.7)解决了我的问题。如果您像我一样从 docker 运行它lts-apline
,那么您现在必须切换到不同的映像。