3-5-3-haproxy-gpc0计数器说明
如何理解和使用HAProxy的gpc0计数
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
stats socket /var/run/haproxy.stat mode 600 level operator
maxconn 4096
user haproxy
group haproxy
daemon
defaults
log global
mode http
option httplog
option dontlognull
retries 3
option redispatch
maxconn 2000
contimeout 5000
clitimeout 50000
srvtimeout 50000
frontend http
bind *:2550
stick-table type ip size 200k expire 10m store gpc0
# check the source before tracking counters, that will allow it to
# expire the entry even if there is still activity.
acl whitelist src 192.168.1.154
acl source_is_abuser src_get_gpc0(http) gt 0
use_backend ease-up-y0 if source_is_abuser
tcp-request connection track-sc1 src if !source_is_abuser
acl is_test1 hdr_sub(host) -i test1.com
acl is_test2 hdr_sub(host) -i test2.com
use_backend test1 if is_test1
use_backend test2 if is_test2
backend test1
stick-table type ip size 200k expire 30s store conn_rate(100s),bytes_out_rate(60s)
acl whitelist src 192.168.1.154
# values below are specific to the backend
tcp-request content track-sc2 src
acl conn_rate_abuse sc2_conn_rate gt 3
acl data_rate_abuse sc2_bytes_out_rate gt 20000000
# abuse is marked in the frontend so that it's shared between all sites
acl mark_as_abuser sc1_inc_gpc0 gt 0
tcp-request content reject if conn_rate_abuse !whitelist mark_as_abuser
tcp-request content reject if data_rate_abuse mark_as_abuser
server local_apache localhost:80
backend test2
stick-table type ip size 200k expire 1m store conn_rate(100s),bytes_out_rate(60s)
acl whitelist src 192.168.1.154
# values below are specific to the backend
tcp-request content track-sc2 src
acl conn_rate_abuse sc2_conn_rate gt 5
acl data_rate_abuse sc2_bytes_out_rate gt 20000000
# abuse is marked in the frontend so that it's shared between all sites
acl mark_as_abuser sc1_inc_gpc0 gt 0
tcp-request content reject if conn_rate_abuse !whitelist mark_as_abuser
tcp-request content reject if data_rate_abuse mark_as_abuser
server local_apache localhost:80
backend ease-up-y0
mode http
errorfile 503 /etc/haproxy/errors/503rate.http
整个配置实现如下目的: 1.根据主机头判断是test1.com还是test2.com , 然后发到对应的backend服务器 2.来自192.168.1.154的访问不受访问速率限制 3.如果100秒之内平均连接速率或者发送的字节数速率超过限制 , 则使用ease-up-y0这个backend处理 , 将持续返回503错误给用户。
下边来解说一下我们关注的限速部分的配置,我将按照逻辑的顺序说明,而不是配置文件中的位置。
针对
backend test1, 我们定义一个stick-table,key类型是ip地址 , 表项最多200K个 , 表项自动过期时间3分钟 ,存储2个数据 :100秒内本IP新建connection的速率 ,60秒内本IP向外发送数据大小的比率stick-table type ip size 200k expire 3m store conn_rate(100s),bytes_out_rate(60s)stick-table中每个IP表项有50bytes大小 , 加上connection rate和bytes out rate各12bytes。所以每个表项占用74bytes内存 ,74*200*1024/1024*1024 ~= 14.11MBytes。所以整个stick-table占用14Mbytes内存。将请求的源
ip地址作为key, 存入当前stick-table的sc2计数器内(官方的建议是sc0用于frontend,sc1用于backend)。tcp-request content track-sc2 src如果
100秒内新建连接速率大于3, 则标记acl conn_rate_abuse如果60秒内发送数据的数量大于20000000 bytes, 则标记acl data_rate_abuseacl conn_rate_abuse sc2_conn_rate gt 3 acl data_rate_abuse sc2_bytes_out_rate gt 20000000接下来这段真正执行这些规则。
acl mark_as_abuser sc1_inc_gpc0 gt 0 tcp-request content reject if conn_rate_abuse !whitelist mark_as_abuser tcp-request content reject if data_rate_abuse mark_as_abuser这段配置比较晦涩难懂,但并不复杂。
gpc0是一个通用计数器 ,sc1_inc_gpc0是gpc0计数器增量(我们在frontend配置中使用)tcp-request content reject if conn_rate_abuse !whitelist mark_as_abuser这一行说明 , 无论用户违反了连接速率或者发送
byte速率的限制 , 而且用户不在白名单中 , 则frontend中的gpc0计数器的值会增加。sc1_inc_gpc0永远返回真值 ,根据短路求值的原则,如果conn_rate_abuse或data_rate_abuse不为真值 , 则mark_as_abuser规则不会被触发执行。上边的
gpc0计数器 , 会在frontend中被处理stick-table type ip size 200k expire 10m store gpc0 # check the source before tracking counters, that will allow it to # expire the entry even if there is still activity. acl whitelist src 192.168.1.154 acl source_is_abuser src_get_gpc0(http) gt 0 use_backend ease-up-y0 if source_is_abuser tcp-request connection track-sc1 src if !source_is_abuser在
frontend我们声明了一个stick-table, 用于存储per source ip的通用计数器。如果这个计数器的值被backend增加了(大于0)则使用ease-up-y0这个backend服务器 , 用户会被返回一个503错误页面。 一旦用户触发了规则,则这个source ip将不会再被跟踪 , 也就是说这个source ip会一直被返回503错误。直到这个source ip表项过期 , 本例中是10分钟(expire 10m)。