在这篇博文中,你将学习如何使用Runtime API动态配置HAProxy。
要了解有关HAProxy配置的更多信息,请参阅我们的博客文章HAProxy配置的四个基本部分。
在过去的15年中,HAProxy以其可靠性,卓越的性能,可扩展的功能和先进的安全性而闻名。这是相对较少众所周知,HAProxy的核心基石之一是运行时API,它提供了非常强大的动态配置功能,没有服务重载或重新启动。
Runtime API的动态配置功能的早期改进是由高级HAProxy用户(如Airbnb和Yelp)通过开发SmartStack(一种开创性的自动服务发现和注册平台)的请求推动的。
在这篇博文中,我们将带你了解HAProxy Runtime API及其一些关键功能,例如动态配置ACL,粘贴表和TLS密钥的功能。除此之外,它还允许改进与服务发现工具和编排系统的集成,增强geolocation定位功能,启用自适应安全策略,提高SSL / TLS集群的效率等等
入门
HAProxy Runtime API的起源可以追溯到我们希望为HAProxy创建完整的配置和统计API,其命令在运行时将立即生效。我们在此API中的早期功能之一当然是能够检索详细的实时统计信息。此外,与仅支持HTTP的典型新API不同,HAProxy Runtime API始终可通过TCP和Unix套接字访问。这就是为什么我们有时仍然将它称为HAProxy stats套接字或仅仅是套接字,以及为什么用于启用Runtime API的配置指令具有相同的名称。
使用以下示例在HAProxy配置中启用运行时API:
global
stats socket ipv4@127.0.0.1:9999 level admin
stats socket /var/run/haproxy.sock mode 666 level admin
stats timeout 2m
了以交互方式测试或执行命令,可以使用socat提供的交互式命令提示符方便地访问Runtime API :
[root@node-www.linuxea.com]# socat readline /var/run/hapee-lb.sock
[root@node-www.linuxea.com]# socat readline tcp4-connect:127.0.0.1:9999
请注意,为了实现上述功能,你的socat版本需要使用GNU Readline支持进行编译。这可以通过运行来验证socat -V | grep READLINE
。如果输出socat -V
未提及READLINE,或者它提到undef READLINE,或者运行实际命令会产生错误未知设备/地址“readline”,则表示你的版本没有readline支持。
要从脚本访问Runtime API,或者作为上面显示的交互式用法的替代,可以使用以下命令
[root@node-www.linuxea.com]# echo "help" | socat stdio /var/run/haproxy.sock
[root@node-www.linuxea.com]# echo "help" | socat stdio tcp4-connect:127.0.0.1:9999
最后,作为socat的替代方案,可以使用来自netcat包的命令nc。在这种情况下,请使用的netcat,OpenBSD的版本的netcat ; 它还支持连接到Unix域套接字的选项。nc -U
从Runtime API开始的最佳方法是执行一个简单的请求,返回所有可用命令的列表。这是通过向help
API 发送或任何未知命令来完成的。以下是“help”的实际输出,在HAProxy版本1.9上执行
[root@node-www.linuxea.com /usr/local/haproxy-1.9.0/contrib/halog]# echo "@1;help" | socat stdio /var/run/haproxy.sock
Unknown command. Please enter one of the following commands only :
help : this message
prompt : toggle interactive mode with prompt
quit : disconnect
show sess [id] : report the list of current sessions or dump this session
shutdown session : kill a specific session
shutdown sessions server : kill sessions on a server
clear counters : clear max statistics counters (add 'all' for all counters)
show info : report information about the running process
show stat : report counters for each proxy and server
show schema json : report schema used for stats
disable agent : disable agent checks (use 'set server' instead)
disable health : disable health checks (use 'set server' instead)
disable server : disable a server for maintenance (use 'set server' instead)
enable agent : enable agent checks (use 'set server' instead)
enable health : enable health checks (use 'set server' instead)
enable server : enable a disabled server (use 'set server' instead)
set maxconn server : change a server's maxconn setting
set server : change a server's state, weight or address
get weight : report a server's current weight
set weight : change a server's weight (deprecated)
show resolvers [id]: dumps counters from all resolvers section and
associated name servers
clear table : remove an entry from a table
set table [id] : update or create a table entry's data
show table [id]: report table usage stats or dump this table's contents
disable frontend : temporarily disable specific frontend
enable frontend : re-enable specific frontend
set maxconn frontend : change a frontend's maxconn setting
show servers state [id]: dump volatile server information (for backend <id>)
show backend : list backends in the current running config
shutdown frontend : stop a specific frontend
set dynamic-cookie-key backend : change a backend secret key for dynamic cookies
enable dynamic-cookie backend : enable dynamic cookies on a specific backend
disable dynamic-cookie backend : disable dynamic cookies on a specific backend
show errors : report last request and response errors for each proxy
set maxconn global : change the per-process maxconn setting
set rate-limit : change a rate limiting value
set severity-output [none|number|string] : set presence of severity level in feedback information
set timeout : change a timeout setting
show env [var] : dump environment variables known to the process
show cli sockets : dump list of cli sockets
show cli level : display the level of the current CLI session
show fd [num] : dump list of file descriptors in use
show activity : show per-thread activity stats (for support/developers)
operator : lower the level of the current CLI session to operator
user : lower the level of the current CLI session to user
show startup-logs : report logs emitted during HAProxy startup
show cache : show cache status
add acl : add acl entry
clear acl <id> : clear the content of this acl
del acl : delete acl entry
get acl : report the patterns matching a sample for an ACL
show acl [id] : report available acls or dump an acl's contents
add map : add map entry
clear map <id> : clear the content of this map
del map : delete map entry
get map : report the keys and values matching a sample for a map
set map : modify map entry
show map [id] : report available maps or dump a map's contents
show pools : report information about the memory pools usage
show profiling : show CPU profiling options
set profiling : enable/disable CPU profiling
检索统计数据
有关在进入Runtime API更强大的命令之前的简单介绍,让我演示从HAProxy获取实时统计信息的方法。
用于检索实时统计数据的众所周知的方法之一是通过HAProxy的内置HTML网页。这些统计信息以简单直接的方式格式化,可以在HAProxy中配置统计信息uri并访问统计信息URL后获取。
也可以通过HAProxy Runtime API获取相同的完整和原始信息。API命令命名为show stat
:
show stat
命令的输出将以CSV格式提供。
统计信息输出包含80多个不同的度量标准。为了快速将其转换为更短且人类可读的输出,我们可以使用标准命令行工具。下面是一个显示所选数据子集并每两秒刷新一次的示例:
[root@node-www.linuxea.com ~]# watch 'echo "@1;show stat" | socat stdio /var/run/haproxy.sock | cut -d "," -f 1-2,5-10,34-36 | column -s, -t'
Every 2.0s: echo "@1;show stat" | socat stdio /var/run/haproxy.sock | cut -d "," -f 1-2,5-10,34-36 | column -s, -t Wed Jun 5 16:39:10 2019
# pxname svname scur smax slim stot bin bout rate rate_lim rate_max
stats FRONTEND 0 0 100000 0 0 0 0 0 0
stats BACKEND 0 0 10000 0 0 0 0 0
frontend-web.com FRONTEND 0 1 100000 31 21276 7385 0 0 6
backend-linuxea.com etcd1 0 1 11 7546 2585 0 2
backend-linuxea.com etcd2 0 1 10 6860 2430 0 2
backend-linuxea.com etcd3 0 1 10 6870 2370 0 2
backend-linuxea.com BACKEND 0 1 10000 31 21276 7385 0 6
通过使用cut
上面的命令,我们将选择范围缩小到对快速和汇总监视有用的字段:
- scur:当前会话数
- smax:自HAProxy重新加载/重启或重置统计信息以来所见的最高会话数
- slim:配置会话数上限
- stot:到目前为止已处理的累计会话数
- bin:中的字节数
- bout:字节输出
- rate:平均每秒会话数,基于1秒计算
- rate_lim:配置每秒新会话的上限
- rate_max:自HAProxy重新加载/重新启动或重置其统计信息以来,每秒看到的最大新会话数
有关show stat
输出中可用的所有字段的列表和说明,请参阅“ HAProxy管理指南”的9.1节。
管理服务器和代理
使用Runtime API,你可以禁用和启用服务器,或逐渐消除流量。你还可以启用和禁用运行状况检查,启用和禁用前端,以及更改分配给服务器的负载平衡权重。我们来看几个例子。
禁用启用节点
如果要逐渐从特定服务器中消耗流量,请使用set server
带有state
参数set 的命令来排除:
- drain 一个节点
echo "@1;set server backend-linuxea.com/etcd1 state drain"|socat stdio /var/run/haproxy.sock
而后通过状态页面查看
- 再次接收
echo "@1;set server backend-linuxea.com/etcd1 state ready"|socat stdio /var/run/haproxy.sock
这个过程我简单使用while观察也可以
[root@DS-VM-Node99 ~]# while true;do curl 172.25.10.245:2379 && sleep 1;done
172.25.50.250
172.25.10.245
172.25.6.37
172.25.50.250
172.25.10.245
172.25.6.37
172.25.50.250
172.25.10.245
172.25.6.37
172.25.50.250
172.25.10.245
172.25.6.37
172.25.50.250
172.25.10.245
172.25.50.250
172.25.10.245
172.25.50.250
172.25.10.245
172.25.50.250
172.25.10.245
172.25.50.250
172.25.10.245
172.25.50.250
172.25.10.245
172.25.50.250
172.25.10.245
172.25.6.37
172.25.50.250
172.25.10.245
172.25.6.37
172.25.50.250
172.25.10.245
172.25.6.37
当服务器处于drain模式时,HAProxy仍会定期发送健康检查。你也可以通过将服务器的状态设置为maint而不是drain来阻止它们。耗尽服务器逐渐将其从负载平衡旋转中取出,而将其置于维护模式与立即禁用它相同。
健康状态检查
如果你只想停止运行状况检查,请使用disable health
命令,如下所示:
- 关闭健康检查
echo "@1; disable health backend-linuxea.com/etcd1 "|socat stdio /var/run/haproxy.sock
- 启用健康检查
echo "@1; enable health backend-linuxea.com/etcd1 "|socat stdio /var/run/haproxy.sock
权重
或者,如果你想向服务器发送更多或更少的流量,你可以更改其权重。使用set server
带有weight
参数的命令:
- 按原始值的百分比更改重量
echo "@1; set server backend-linuxea.com/etcd1 weight 50% "|socat stdio /var/run/haproxy.sock
修改完成后就变成了蓝色,并且接收的请求也降低
- 按其他服务器的比例改变重量
echo "@1; set server backend-linuxea.com/etcd1 weight 100% "|socat stdio /var/run/haproxy.sock
关闭打开frontend
你可以做的其他事情是停止前端代理的所有流量。使用此disable frontend
命令从前端释放端口绑定。如果原始端口导致问题,你可以使用此端口将该端口与不同的前端相关联。这是一个例子:
- 禁用
echo "@1; disable frontend frontend-web.com "|socat stdio /var/run/haproxy.sock
图示:
- 开启
echo "@1; enable frontend frontend-web.com "|socat stdio /var/run/haproxy.sock
图示:
更新Stick表
Stick表是另一个非常强大,但在HAProxy中使用简单。Stick表允许跨请求跟踪任意客户端信息,因此它们用于创建“sticky”会话,实施安全保护,设置限制以及维护计数器和列表等目的。
Stick table基于haproxy的高性能 弹性二叉树。Ebtrees允许这些表包含数百万条记录,同时保持极快的访问速度。
Runtime API允许在运行时添加,删除,搜索和更新sticky表条目。在下面的示例中,我们将创建一个包含100万个条目的表格,以跟踪来自各个客户端IP的请求率。我们将限制每秒最多30个请求,并且在10秒的时间段内继续以高于该限制的速率发送请求的IP地址将被拒绝,时间为15分钟。
frontend www.linuxea.com
bind *:2379
mode http
option httplog
stick-table type ip size 1m expire 15m store gpt0,http_req_rate(10s)
http-request allow if { src -f /etc/haproxy/whitelist.lst }
http-request track-sc0 src
acl abuse src_http_req_rate ge 30
http-request sc-set-gpt0(0) 1 if abuse
http-request deny if { sc0_get_gpt0 ge 1 }
touch /etc/haproxy/whitelist.lst
echo "reload" | socat stdio /var/run/haproxy.sock
测试下
[root@DS-www.linuxea.com ~]# while true;do curl 172.25.10.245:2379 ; done
172.25.10.245
172.25.50.250
172.25.6.37
172.25.10.245
172.25.50.250
172.25.6.37
172.25.10.245
172.25.50.250
172.25.6.37
172.25.10.245
172.25.50.250
172.25.6.37
172.25.10.245
172.25.50.250
172.25.6.37
172.25.10.245
172.25.50.250
172.25.6.37
172.25.10.245
172.25.50.250
172.25.6.37
172.25.10.245
<html><body><h1>403 Forbidden</h1>
Request forbidden by administrative rules.
</body></html>
<html><body><h1>403 Forbidden</h1>
Request forbidden by administrative rules.
</body></html>
<html><body><h1>403 Forbidden</h1>
Request forbidden by administrative rules.
</body></html>
<html><body><h1>403 Forbidden</h1>
Request forbidden by administrative rules.
</body></html>
<html><body><h1>403 Forbidden</h1>
Request forbidden by administrative rules.
</body></html>
<html><body><h1>403 Forbidden</h1>
Request forbidden by administrative rules.
在/etc/haproxy/whitelist.lst
文件中可以存放被放行的IP,而后reload生效即可。
那我们在Runtime API中看下
[root@node-www.linuxea.com ~]# echo "@1; show table frontend-web.com "|socat stdio /var/run/haproxy.sock
# table: frontend-web.com, type: ip, size:1048576, used:1
0x7fbe7401b670: key=172.25.50.250 use=0 exp=809045 gpt0=1 http_req_rate(10000)=0
我们可以通过api设置GPT0来释放
12065> set table frontend-web.com key 172.25.50.250 data.gpt0 0
12065> show table frontend-web.com data.gpt0 gt 0
# table: frontend-web.com, type: ip, size:1048576, used:2
12065> show table frontend-web.com
# table: frontend-web.com, type: ip, size:1048576, used:1
0x1c0f390: key=127.0.0.1 use=0 exp=659815 gpt0=0 http_req_rate(10000)=0
或者直接删除
12065> clear table frontend-web.com key 172.25.50.250
12065> show table frontend-web.com data.gpt0 gt 0
# table: frontend-web.com, type: ip, size:1048576, used:1
12065> show table frontend-web.com
# table: frontend-web.com, type: ip, size:1048576, used:1
0x1c0f390: key=127.0.0.1 use=0 exp=659815 gpt0=0 http_req_rate(10000)=0
更新ACL
为了扩展上述限制传入HTTP请求的示例,我们假设现在要将现有速率限制从每秒30个更改为60个请求。
为此,HAProxy Runtime API肯定允许我们在运行时更改ACL。我们将执行命令“show acl”以查看配置的ACL,然后识别我们要修改的ACL,最后执行实际修改。修改将包括添加新值,然后删除旧值以完成转换。
完整的会话可能如下所示:
12065> show acl
# id (file) description
0 (/etc/haproxy/whitelist.lst) pattern loaded from file '/etc/haproxy/whitelist.lst' used by acl at file '/etc/haproxy/haproxy.cfg' line 77
1 () acl 'src' file '/etc/haproxy/haproxy.cfg' line 77
2 () acl 'src_http_req_rate' file '/etc/haproxy/haproxy.cfg' line 79
3 () acl 'sc0_get_gpt0' file '/etc/haproxy/haproxy.cfg' line 81
-1 () acl 'http_auth' file 'internal-stats-auth-compat' line 0
我们仅仅对src_http_req_rate感兴趣,查看下
12065> show acl #2
0x1b87610 30:
而后添加一个新的60
12065> add acl #2 60
此时你会看到有两个
12065> show acl #2
0x1b87610 30:
0x1c17a20 60
我们随即将位于30秒的删除,0x1b87610
12065> del acl #2 #0x1b87610
在查看已经只有60s一个配置
12065> show acl #2
0x1c17a20 60
更新白名单和黑名单
再次扩展我们的原始速率限制示例,请注意我们已使用以下配置指令来配置列入白名单的IP地址:
http-request allow if { src -f /etc/haproxy/whitelist.lst }
此配置行告诉HAProxy获取源IP,根据从whitelist.lst加载的IP地址列表进行检查,并在不进一步检查列表中是否找到IP地址的情况下通过请求。
在此示例中,我们将使用Runtime API修改白名单的内容 - 我们将IP地址172.25.50.250添加。像往常一样,为此我们将列出ACL,识别我们想要修改的条目,然后执行实际修改。修改将包括添加新值,然后删除旧值以完成转换。
完整的会话可能如下所示:
12065> show acl
# id (file) description
0 (/etc/haproxy/whitelist.lst) pattern loaded from file '/etc/haproxy/whitelist.lst' used by acl at file '/etc/haproxy/haproxy.cfg' line 77
1 () acl 'src' file '/etc/haproxy/haproxy.cfg' line 77
2 () acl 'src_http_req_rate' file '/etc/haproxy/haproxy.cfg' line 79
3 () acl 'sc0_get_gpt0' file '/etc/haproxy/haproxy.cfg' line 81
-1 () acl 'http_auth' file 'internal-stats-auth-compat' line 0
列出
12065> show acl #0
0x1b87080 10.10.0.96
0x1b870c0 10.10.195.99
添加172.25.50.250
12065> add acl #0 172.25.50.250
在查看即可
12065> show acl #0
0x1b87080 10.10.0.96
0x1b870c0 10.10.195.99
0x1b87610 172.25.50.250
更新TLS
当现有客户端想要在关闭前一个会话后启动新会话时,HAProxy使用tls-ticket-keys来避免密钥重新协商。如果客户端支持tls会话,HAProxy将向其发送包含所有协商会话数据(密码套件,主密钥等)的新会话凭证记录。该记录将使用仅为HAProxy进程知道的密钥加密,确保客户端不会读取或修改数据。
用于加密TLS凭证的是在HAProxy启动时生成的。如果设置了主动 - 主动HAProxy群集并且客户端在节点之间移动,则必须经常重新协商密钥,因为群集中的其他节点将无法理解使用特定于节点的密钥加密的故障单。为了避免这种情况,可以将秘密放入文件中并定期轮叫它们以保持完美的前向保密。这样,集群中的所有节点都将使用完全相同的密钥集,客户端将能够在HAProxy节点之间移动而没有任何副作用。
这可以通过更新包含键的文件并手动重新加载HAProxy来完成,但也可以在运行时使用HAProxy Runtime API完成。
完整的会话可能如下所示:
# List keys files
> show tls-keys
# id (file)
0 (/dev/shm/hapee_ticket_keys.txt)
# List keys in a particular file
> show tls-keys #0
# id secret
# 0 (/dev/shm/hapee_ticket_keys.txt)
0.0 vaL65b3ns0mAJbiQRGiQZ84H4C9N1dZAyDYrHXVqG6KRDuXCo8mpwfk6+xPtlM1m
0.1 fQxhSJT8sBKNb6JAFZT11UkzplfXEI1uUijPQUTBysZpNqzT26s2RVARxCoo5E52
0.2 QtxrjBbPrX6z/PljdHIFqmHMH2/Rc5zZzIKklcfBPJa01G6PU9Dp9ixcibeisZxU
# Update key
> set ssl tls-keys #0 CaF7HpWr0gUByzxDqlbvYXCFT2zqmhnKFAdbM4MyQHfty974QO31Pn1OLJIR92rk
TLS ticket key updated!
# Verify successful update
> show tls-keys #0
# id secret
# 0 (/dev/shm/hapee_ticket_keys.txt)
0.0 fQxhSJT8sBKNb6JAFZT11UkzplfXEI1uUijPQUTBysZpNqzT26s2RVARxCoo5E52
0.1 QtxrjBbPrX6z/PljdHIFqmHMH2/Rc5zZzIKklcfBPJa01G6PU9Dp9ixcibeisZxU
0.2 CaF7HpWr0gUByzxDqlbvYXCFT2zqmhnKFAdbM4MyQHfty974QO31Pn1OLJIR92rk
显示错误
如上所述,HAProxy将错误记录到日志文件中。例如,如果我们发送简单的无效流量,如下所示:
[root@node-www.linuxea.com ~]# echo "This is invalid trafficnnMore invalid traffic" | nc -v 172.25.10.245 2379
Ncat: Version 7.50 ( https://nmap.org/ncat )
Ncat: Connected to 172.25.10.245:2379.
HTTP/1.0 400 Bad request
Cache-Control: no-cache
Connection: close
Content-Type: text/html
<html><body><h1>400 Bad request</h1>
Your browser sent an invalid request.
</body></html>
Ncat: 48 bytes sent, 187 bytes received in 0.01 seconds.
然后日志将显示以下错误:
Jun 6 17:47:11 host-172-25-10-245 haproxy[12065]: 172.25.10.245:35540 [06/Jun/2019:17:47:11.193] frontend-web.com frontend-web.com/<NOSRV> -1/-1/-1/-1/0 400 187 - - PR-- 1/1/0/0/0 0/0 "<BADREQ>"
但是为了获得有关请求的更多信息,甚至查看请求的内容,我们可以使用Runtime API命令“show errors”:
[root@node-www.linuxea.com ~]# echo "@1;show errors" | socat stdio /var/run/haproxy.sock
Total events captured on [06/Jun/2019:17:48:25.444] : 3
[06/Jun/2019:17:47:49.265] frontend frontend-web.com (#3): invalid request
backend <NONE> (#-1), server <NONE> (#-1), event #2, src 172.25.10.245:35664
buffer starts at 0 (including 0 out), 16372 free,
len 12, wraps at 16384, error at position 11
stream #35060, stream flags 0x00000000, tx flags 0x00000000
HTTP msg state MSG_ERROR(26), msg flags 0x00000000
HTTP chunk len 0 bytes, HTTP body len 0 bytes, channel flags 0x00d08002 :
00000 show errorsn
Dumping 会话
根据日志记录配置,可以将所有连接记录到HAProxy的日志文件中。但是,像往常一样,只有在HAProxy从后端服务器获得回复或其中一个定时器到期后才会记录它们。在涉及长时间超时或会话需要很长时间才能完成的情况下,这可能会导致日志似乎永远不会到达。在这种情况下,Runtime API命令“show sess”可用于转储所有当前会话及其相关信息:
[root@node-www.linuxea.com ~]# echo "@1; show sess " | socat stdio /var/run/haproxy.sock
0x7fbe7c016760: proto=tcpv4 src=172.25.50.250:19548 fe=frontend-web.com be=backend-linuxea.com srv=etcd3 ts=00 age=0s calls=1 cpu=77210 lat=9950 rq[f=cc08000h,i=0,an=8000h,rx=,wx=,ax=] rp[f=80000000h,i=0,an=00h,rx=,wx=,ax=] s0=[7,40008h,fd=20,ex=] s1=[5,110h,fd=24,ex=5s] exp=5s
0x1c01240: proto=sockpair ts=00 age=0s calls=1 cpu=9303 lat=17664 rq[f=c0c220h,i=0,an=00h,rx=,wx=,ax=] rp[f=80008002h,i=0,an=00h,rx=,wx=,ax=] s0=[7,280008h,fd=25,ex=] s1=[7,204018h,fd=-1,ex=] exp=
在上面的例子中,我们可以看到两个会话:第一个是IPv4会话; 第二个是与我们调用Runtime API相关的会话。从查看输出,我们可以,例如,识别IPv4会话fe=frontend-web.com be=backend-linuxea.com。此外,为了帮助我们进一步解决复杂问题,我们可以使用命令“show sess”将会话ID作为参数提供(“show sess ID”)以获取有关特定会话的更多详细信息。
tcpv4的回话太快,我么查看第二个
[root@node-www.linuxea.com ~]# echo "@1; show sess 0x1c01240 " | socat stdio /var/run/haproxy.sock
0x1c01240: [06/Jun/2019:17:51:44.877386] id=48347 proto=sockpair
flags=0x8, conn_retries=0, srv_conn=(nil), pend_pos=(nil)
frontend=GLOBAL (id=0 mode=tcp), listener=? (id=2) addr=172.25.50.250:81
backend=<NONE> (id=-1 mode=-)
server=<NONE> (id=-1)
task=0x1c0a3f0 (state=0x00 nice=-64 calls=1 exp=<NEVER> tmask=0x1 age=0s)
si[0]=0x1c014d8 (state=EST flags=0x280008 endp0=CS:0x1c01730 exp=<NEVER>, et=0x000)
si[1]=0x1c01518 (state=EST flags=0x204018 endp1=APPCTX:0x1c09eb0 exp=<NEVER>, et=0x000)
co0=0x1c00ec0 ctrl=sockpair xprt=RAW mux=PASS data=STRM target=LISTENER:0x1b7edb0
flags=0x00241300 fd=25 fd.state=22 fd.cache=0 updt=0 fd.tmask=0x1
cs=0x1c01730 csf=0x00001000 ctx=0x1c01750
app1=0x1c09eb0 st0=7 st1=0 st2=3 applet=<CLI> tmask=0x1, nice=-64, calls=1, cpu=0, lat=9846
req=0x1c01250 (f=0xc0c220 an=0x0 pipe=0 tofwd=0 total=22)
an_exp=<NEVER> rex=<NEVER> wex=<NEVER>
buf=0x1c01258 data=0x1be28c0 o=0 p=0 req.next=0 i=0 size=16384
res=0x1c012b0 (f=0x80008000 an=0x0 pipe=0 tofwd=-1 total=0)
an_exp=<NEVER> rex=<NEVER> wex=<NEVER>
buf=0x1c012b8 data=0x1c05a90 o=0 p=0 rsp.next=0 i=0 size=16384
结束会话
除了使用“show sess”显示活动会话外,我们还可以使用Runtime API通过“shutdown session”随意关闭会话:
> shutdown session 0x7fbe7c016760
此类会话将显示在包含标记“K”的日志中,表示它们已关闭。
更新GeoIP数据库
GeoIP数据库将IP地址范围映射到地理位置。这些数据库可以在HAProxy中用于不同的目的。通常,它们用于在HAProxy中本地执行GeoIP查找并将数据提供给后端服务器。然后,后端服务器可以依赖于作为传入请求的一部分可用的信息,不需要特定的GeoIP代码,也不会导致应用程序代码本身的任何减速。
有关将GeoIP与HAProxy配合使用的更多信息,请参阅我们之前的博客文章“ 将GeoIP数据库与HAProxy一起使用”。GeoIP的另一个常见用例是在HAProxy日志中包含客户端国家/地区代码。这可以通过使用以下log-format指令来实现:
以上行将使用map_ip
转换器从映射文件ip-country.lst获取国家/地区代码。基于此格式的日志将如下所示:
Jun 6 17:56:32 host-172-25-10-245 haproxy[12065]: 10.10.0.96:5231 [06/Jun/2019:17:56:32.955] stats stats/<STATS> 0/0/0/0/0 200 23696 - - LR-- 1/1/0/0/0 0/0 "GET /stats HTTP/1.1"
Jun 6 17:56:33 host-172-25-10-245 haproxy[12065]: 10.10.0.96:5232 [06/Jun/2019:17:56:33.010] stats stats/<NOSRV> 0/-1/-1/-1/0 503 212 - - SC-- 1/1/0/0/0 0/0 "GET /favicon.ico HTTP/1.1"
现在,在更新GeoIP数据库方面,我们假设我们在地图文件中有以下新的GeoIP条目:
2.0.0.0/12 FR
3.55.0.0/24 FR
4.16.2.0/23 FR
9.16.10.0/24 FR
我们可以使用Runtime API命令轻松地将它们添加到运行配置中add map
。此外,我们将使用一些bash shell脚本来自动执行数据导入,而不是逐个添加条目:
IFS=$'n'
for ip_country in $(cat /tmp/linuxea-ip.list); do
echo "@1; add map #1 /tmp/ip-country.lst $ip_country"
done | socat stdio /var/run/haproxy.sock
这里会提示,因为这些IP无效
[root@node-www.linuxea.com /var/log]# IFS=$'n'
[root@node-www.linuxea.com /var/log]# for ip_country in $(cat /tmp/linuxea-ip.list); do
> echo "@1; add map #1 /tmp/ip-country.lst $ip_country"
> done | socat stdio /var/run/haproxy.sock
'/tmp/ip-country.lst' is not a valid IPv4 or IPv6 address.
'/tmp/ip-country.lst' is not a valid IPv4 or IPv6 address.
'/tmp/ip-country.lst' is not a valid IPv4 or IPv6 address.
'/tmp/ip-country.lst' is not a valid IPv4 or IPv6 address.
延伸阅读
linuxea:haproxy 1.9中的多线程linuxea:haproxy1.9 了解四个基础部分linuxea:haproxy1.9日志简介