服务器发现大量的TIME_WAIT的解决办法
今天上班,有同事反映公司网站都打不开,于是登陆数据库服务器(win),发现非常卡,于是就重启了服务器。
重新进入系统后,没过多久又出现刚才的问题,查看了下系统进程,发现mysql占用率达到99%,估计是mysql连接出现问题:
netstat -na
192.168.1.103:3306 192.168.1.102:20443 TIME_WAIT
192.168.1.103:3306 192.168.1.102:20444 TIME_WAIT
192.168.1.103:3306 192.168.1.102:20445 TIME_WAIT
192.168.1.103:3306 192.168.1.102:20446 TIME_WAIT
192.168.1.103:3306 192.168.1.102:20447 TIME_WAIT
192.168.1.103:3306 192.168.1.102:20448 TIME_WAIT
192.168.1.103:3306 192.168.1.102:20449 TIME_WAIT
... ...
根据TCPIP协议的三次握手规定,发起socket连接主动关闭的一方 socket会进入TIME_WAIT状态,TIME_WAIT状态会持续2个MSL(Max Segment Lifetime),在Windows下默认为4分钟,即240秒,TIME_WAIT状态下的socket连接不能被回收使用。
具体现象就是对于一个处理巨量短连接的服务器,如果是由server端主动关闭client的连接,将导致server端存在大量的处于TIME_WAIT状态的socket, 甚至比处于Established状态下的socket还要多,严重影响server的处理能力,甚至会耗尽可用的socket,导致停止服务.
TIME_WAIT是TCPIP协议用以保证被重新分配的socket不会受到之前残留的延迟重发报文影响的机制,是必要的逻辑保证.
解决办法:
在HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesTcpipParameters,添加名为TcpTimedWaitDelay的
DWORD键,设置为60,以缩短TIME_WAIT的等待时间
登陆到web服务器(linux):
netstat -ae |grep mysql
tcp 0 0 192.168.1.101:33045 192.168.1.103:mysql TIME_WAIT root 0
tcp 0 0 192.168.1.101:33044 192.168.1.103:mysql TIME_WAIT root 0
tcp 0 0 192.168.1.101:33051 192.168.1.103:mysql TIME_WAIT root 0
tcp 0 0 192.168.1.101:33050 192.168.1.103:mysql TIME_WAIT root 0
tcp 0 0 192.168.1.101:33049 192.168.1.103:mysql TIME_WAIT root 0
tcp 0 0 192.168.1.101:33048 192.168.1.103:mysql TIME_WAIT root 0
tcp 0 0 192.168.1.101:33055 192.168.1.103:mysql TIME_WAIT root 0
tcp 0 0 192.168.1.101:33054 192.168.1.103:mysql TIME_WAIT root 0
tcp 0 0 192.168.1.101:33053 192.168.1.103:mysql TIME_WAIT root 0
... ...
发现系统存在大量TIME_WAIT状态的连接,通过调整内核参数解决,
vim /etc/sysctl.conf
编辑文件,加入以下内容:
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30
然后执行下面命令让参数生效。
/sbin/sysctl -p
修改之后,再用
netstat -ae|grep mysql
tcp 0 0 192.168.1.101:30408 192.168.1.103:mysql ESTABLISHED nobody 3224651
tcp 0 0 192.168.1.101:30417 192.168.1.103:mysql ESTABLISHED nobody 3224673
tcp 0 0 192.168.1.101:30419 192.168.1.103:mysql ESTABLISHED nobody 3224675
这时发现之前大量的TIME_WAIT 已不存在,mysql进程的占用率很快就降下来的,公司网站访问正常了。沈阳众诚志联真诚为您服务
以上只是暂时的解决方法。最终原因是程序代码中没有使用mysql.colse(),才导致大量的mysql TIME_WAIT,所以我们在程序设计中要尽量避免。