统计在一台前端机上高峰时间tcp连接的情况,统计命令:
netstat -n | awk '/^tcp/ { s[$nf]} end {for(a in s) print a, s[a]}'
结果:
除了established,可以看到连接数比较多的几个状态是:fin_wait1, time_wait, close_wait, syn_recv和last_ack;下面的文章就这几个状态的产生条件、对系统的影响以及处理方式进行简单描述。
发现存在大量time_wait状态的连接
tcp 0 0 127.0.0.1:3306 127.0.0.1:41378 time_wait
tcp 0 0 127.0.0.1:3306 127.0.0.1:41379 time_wait
tcp 0 0 127.0.0.1:3306 127.0.0.1:39352 time_wait
tcp 0 0 127.0.0.1:3306 127.0.0.1:39350 time_wait
tcp 0 0 127.0.0.1:3306 127.0.0.1:35763 time_wait
tcp 0 0 127.0.0.1:3306 127.0.0.1:39372 time_wait
tcp 0 0 127.0.0.1:3306 127.0.0.1:39373 time_wait
tcp 0 0 127.0.0.1:3306 127.0.0.1:41176 time_wait
通过调整内核参数解决
vi /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让参数生效。
net.ipv4.tcp_syncookies = 1表示开启syn cookies。当出现syn等待队列溢出时,启用cookies来处理,可防范少量syn攻击,默认为0,表示关闭;
net.ipv4.tcp_tw_reuse = 1表示开启重用。允许将time-wait sockets重新用于新的tcp连接,默认为0,表示关闭;
net.ipv4.tcp_tw_recycle = 1表示开启tcp连接中time-wait sockets的快速回收,默认为0,表示关闭。
net.ipv4.tcp_fin_timeout修改系統默认的timeout时间
修改之后,再用命令查看time_wait连接数
netstat -ae|grep “time_wait” |wc –l
发现大量的time_wait 已不存在,mysql进程的占用率很快就降下来的,网站访问正常。
不过很多时候,出现大量的time_wait状态的连接,往往是因为网站程序代码中没有使用mysql.colse(),才导致大量的mysql time_wait.
根据tcp协议定义的3次握手断开连接规定,发起socket主动关闭的一方 socket将进入time_wait状态,time_wait状态将持续2个msl(max segment lifetime),在windows下默认为4分钟,即240秒,time_wait状态下的socket不能被回收使用. 具体现象是对于一个处理大量短连接的服务器,如果是由服务器主动关闭客户端的连接,将导致服务器端存在大量的处于time_wait状态的socket, 甚至比处于established状态下的socket多的多,严重影响服务器的处理能力,甚至耗尽可用的socket,停止服务. time_wait是tcp协议用以保证被重新分配的socket不会受到之前残留的延迟重发报文影响的机制,是必要的逻辑保证.
在hkey_local_machine\system\currentcontrolset\services\tcpip\parameters,添加名为tcptimedwaitdelay的
dword键,设置为60,以缩短time_wait的等待时间
修改之后,再用 netstat -ae|grep mysql tcp 0 0 aaaa:50408 192.168.12.13:mysql established nobody 3224651
tcp 0 0 aaaa:50417 192.168.12.13:mysql established nobody 3224673
tcp 0 0 aaaa:50419 192.168.12.13:mysql established nobody 3224675
发现大量的time_wait 已不存在,mysql进程的占用率很快就降下来的,各网站访问正常!! 以上只是暂时的解决方法,最后仔细巡查发现是前天新上线的一个系统,程序代码中没有使用mysql.colse(),才导致大量的mysql time_wait
如果你的服务器是windows平台,可以修改下面的注册表键值:
[hkey_local_machine\system\currentcontrolset\services\tcpip\parameters]
"tcptimedwaitdelay"=dword:0000001e
此值是time_wait状态的最长时间。缺省为240秒,最低为30秒,最高为300秒。建议为30秒。
注释:
(
1,tcp结束的过程如下:
server client
-------------- fin --------------> server: fin_wait_1
<------------- ack --------------- client: close_wait server:fin_wait_2
<------------- fin --------------- client发出fin之后就关闭
-------------- ack -------------> server发出ack后进入time_wait状态
time_wait的默认时间是2倍的mls,就是240秒钟。mls是tcp片在网上的最长存活时间。
time_wait的主要作用是保证关闭的tcp端口不立即被使用。因为当网络存在延迟时,可能当某个端口被关闭后,网络中还有一些重传的tcp片在发向这个端口,如果这个端口立即建立新的tcp连接,则可能会有影响。所以使用2倍的msl时间来限制这个端口立即被使用。
现在的问题在于,4分钟的时间有点长。
因此,time_wait的影响,我想,首先每个tcp连接都各自有个数据结构,叫tcp control block.time_wait的时候这个数据结构没有被释放。所以当有太多的tcp连接时,内存可能会被占用很多。
2,to valorz:time_wait状态也称为2msl等待状态,而不是2mls,笔误吧!
每个tcp报文在网络内的最长时间,就称为msl(maximum segment lifetime),它的作用和ip数据包的ttl类似。
rfc793指出,msl的值是2分钟,但是在实际的实现中,常用的值有以下三种:30秒,1分钟,2分钟。
注意一个问题,进入time_wait状态的一般情况下是客户端,大多数服务器端一般执行被动关闭,不会进入time_wait状态,当在服务器端关闭某个服务再重新启动时,它是会进入time_wait状态的。
举例:
1.客户端连接服务器的80服务,这时客户端会启用一个本地的端口访问服务器的80,访问完成后关闭此连接,立刻再次访问服务器的80,这时客户端会启用另一个本地的端口,而不是刚才使用的那个本地端口。原因就是刚才的那个连接还处于time_wait状态。
2.客户端连接服务器的80服务,这时服务器关闭80端口,立即再次重启80端口的服务,这时可能不会成功启动,原因也是服务器的连接还处于time_wait状态。
windows
tcptimedwaitdelay和maxuserport设置
描述:确定 tcp/ip 可释放已关闭连接并重用其资源前,必须经过的时间。 关闭和释放之间的此时间间隔通称 time_wait 状态或两倍最大段生命周期(2msl)状态。 此时间期间,重新打开到客户机和服务器的连接的成本少于建立新连接。 减少此条目的值允许 tcp/ip 更快地释放已关闭的连接,为新连接提供更多资源。如果运行的应用程序需要快速释放和创建新连接,而且由于 time_wait 中存在很多连接,导致低吞吐量,则调整此参数。 如何查看或设置: 使用 regedit 命令访问 hkey_local_machine/system/currentcontrolset/ services/tcpip/parameters 注册表子键并创建名为 tcptimedwaitdelay 的新 reg_dword 值。 将此值设置为十进制 30,其为十六进制 0x0000001e。 该值将等待时间设置为 30 秒。 停止并重新启动系统。 缺省值:0xf0,它将等待时间设置为 240 秒(4 分钟)。 建议值:最小值为 0x1e,它将等待时间设置为 30 秒。 maxuserport 描述:确定在应用程序从系统请求可用用户端口时,tcp/ip 可指定的最高端口号。 如何查看或设置: 使用 regedit 命令访问 hkey_local_machine/system/currentcontrolset/ services/tcpip/parameters 注册表子键并创建名为 maxuserport 的新 reg_dword 值。 停止并重新启动系统。 缺省值:无 建议值:至少十进制 32768。 注:当在 windows nt 或 windows 2000 操作系统上调整 websphere application server 时,同时使用这两个参数。 希望本站的知识能给您的工作、学习和生活带来方便和乐趣!