尝试使用以下命令在 haproxy 1.5-18 上实现速率限制:
frontend
stick-table type ip size 100k expire 30s store conn_rate(3s) #connection rate
stick-table type ip size 1m expire 10s store gpc0,http_req_rate(10s) #http req rate
stick-table type ip size 100k expire 30s store conn_cur #concurrent connections
tcp-request connection track-sc1 src
tcp-request connection reject if { sc1_conn_rate ge 20 }
tcp-request connection reject if { src_get_gpc0(front) gt 50 }
tcp-request connection reject if { sc1_conn_cur ge 50 }
backend
acl abuse src_http_req_rate(front) ge 10
acl flag_abuser src_inc_gpc0(front)
tcp-request content reject if abuse flag_abuser
这会起作用,因为http_req_rate
会启动并禁止滥用者。但如果我删除规则http_req_rate
,只留下这些
frontend
stick-table type ip size 100k expire 30s store conn_rate(3s) #connection rate
stick-table type ip size 100k expire 30s store conn_cur #concurrent connections
tcp-request connection track-sc1 src
tcp-request connection reject if { sc1_conn_rate ge 50 }
tcp-request connection reject if { sc1_conn_cur ge 50 }
那么滥用者不会被禁止,只是不允许发起超过 50 个连接。通过监视 Apache 队列,“滥用者”将保持不超过 50 个连接处于忙碌状态。
虽然这很好,因为一个 IP 不会达到最大值MaxClients
,但这也不是最好的,因为 5 个 IP 会达到 - 5*50 = 250,考虑到MaxClients
250。
难道不应该禁止全部滥用 IP 的新连接和已建立的连接?
-- 请不要向我指出 exceliance 文章,他们的例子甚至都不正确。他们举例说明了src_conn_cur
和src_conn_rate
,而他们应该使用sc1_*
(因为前面的那些不起作用)。
答案1
如果你的 haproxy 在互联网上运行(即具有公共 IP,不在防火墙后面等)... 您可以使用 iptables 进一步限制堆栈的速率...
iptables -I 输入 -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --set
iptables -I INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --update --seconds 60 --hitcount 10 -j DROP
因此 haproxy 守护进程甚至不会获得流量,这意味着更高的效率和更少的负载。这只有当 haproxy 具有公共 IP 时才会起作用(例如,不在 amazon elb 后面)