本文共 2319 字,大约阅读时间需要 7 分钟。
现象1:在haproxy中间件层查看netstat会有大量的time_wait,大概有几万个以上
现象2:查看haproxy日志会有部分显示端口耗尽
Jan 9 14:59:04 127.0.0.1 haproxy[37]: Connect() failed for backend ha-proxy: no free ports.
Jan 9 14:59:04 127.0.0.1 haproxy[38]: Connect() failed for backend ha-proxy: no free ports. Jan 9 14:59:04 127.0.0.1 haproxy[38]: Connect() failed for backend ha-proxy: no free ports. Jan 9 14:59:04 127.0.0.1 haproxy[38]: Connect() failed for backend ha-proxy: no free ports. Jan 9 14:59:04 127.0.0.1 haproxy[38]: Connect() failed for backend ha-proxy: no free ports. Jan 9 14:59:04 127.0.0.1 haproxy[35]: Connect() failed for backend ha-proxy: no free ports.现象3:mysql连接偶尔报错
ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0
ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0 ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0 ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0现象4:登录mysql以后show processlist会存在部分unauthenticated user,reading from net
短时间内大量的短连接导致haproxy端口耗尽,通过查看cat /proc/sys/net/ipv4/ip_local_port_range 的数值可得知当前可使用的端口范围,我这里默认是32768到61000;即使将其调整到1024到65535,在大量短连接情况下效果也是很有限的,因为处于time_wait状态的端口没法复用。
为何会出现大量的time_wait:因为tcp连接断开时,主动发起tcp的一方会处于time_wait,而这个持续时间由内核参数/proc/sys/net/ipv4/tcp_fin_timeout控制,我这里是60s,也就是说,我的可用端口数量是65535-1024=28232,那我平均每秒的新建连接数超过28232/60=470时就必然会出现端口耗尽的情况;假如我只调整端口范围的话,那我平均每秒的新建连接数(65535-1024)/60=1075时也会出现端口耗尽的情况,提升空间不是很大
如何查看haproxy的每秒新建连接数:有两种方法,第一种是简单地过滤某一秒的haproxy的日志行数,每新建一个连接,haproxy日志都会加一行记录;另外一种方法是使用socat打印当前haproxy的各种信息(haproxy开了多进程模式以后貌似不准),下面的信息就显示当前每秒新建连接337个,进程启动以后历史最大为1172个
echo "show info"| socat stdio /opt/udb/instance/haproxy/35d96a08-c230-4a32-9de5-5fe6b80eff46/stats |grep -i conn
Maxconn: 6000 Hard_maxconn: 6000 CurrConns: 170 CumConns: 1195526325 ConnRate: 337 ConnRateLimit: 0 MaxConnRate: 1172