分享

大量短连接导致haproxy服务器端口耗尽

 quasiceo 2018-08-17

现象

现象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

优化方法

优化方法有好几种,大概以下
1 业务层使用长连接
2 修改内核参数/proc/sys/net/ipv4/tcp_tw_reuse,将其改为1,并确保客服端和服务器端的/proc/sys/net/ipv4/tcp_timestamps也为1,这样就可以复用处于time_wait状态的端口。由于时间戳是精确到秒的,这样设置以后,haproxy能够承受的每秒最大短连接数量就是端口数量了,即28232
3 mysql前端加memcache或者redis缓存,减少每秒打开的连接数


参考
https://www./blog/haproxy-high-mysql-request-rate-and-tcp-source-port-exhaustion/


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多