您现在的位置: 365建站网 > 365学习 > windows/linux下TIME_WAIT状态的TCP连接的回收时间

windows/linux下TIME_WAIT状态的TCP连接的回收时间

文章来源:365jz.com     点击数:89    更新时间:2020-04-30 09:23   参与评论

TIME_WAIT是什么?


TIME_WAIT是表示系统在等待客户端响应,以便再次连接时候能快速响应。TCP协议的三次握手中规定发起socket主动关闭的一方 socket将进入TIME_WAIT状态,TIME_WAIT状态将持续2个MSL(Max Segment Lifetime)。我们看下tcp的三次握手机制:


image.png


从 上面的示意图可以看得出来,TIME_WAIT是主动关闭连接的一方保持的状态,从而进入TIME_WAIT的状态,然后在保持这个状态2MSL(max segment lifetime)时间之后,彻底关闭回收资源。为什么要这么做?明明就已经主动关闭连接了为啥还要保持资源一段时间呢?这个是TCP/IP的设计者规定 的,主要出于以下两个方面的考虑:


1.防止上一次连接中的包,迷路后重新出现,影响新连接(经过2MSL,上一次连接中所有的重复包都会消失)

2. 可靠的关闭TCP连接。在主动关闭方发送的最后一个 ack(fin) ,有可能丢失,这时被动方会重新发fin, 如果这时主动方处于 CLOSED 状态 ,就会响应 rst 而不是 ack。所以主动方要处于 TIME_WAIT 状态,而不能是 CLOSED 。另外这么设计TIME_WAIT 会定时的回收资源,并不会占用很大资源的,除非短时间内接受大量请求或者受到攻击。

==============Windows操作系统==========

 

查看使用端口数量:cmd-- netsh interface ipv4 show dynamicportrange protocol=tcp

查看建立连接的数量:netsh interface ipv4 show tcpstats


大规模Windows环境下,采用Nginx反向代理服务后,操作系统会产生较多TIME_WAIT的TCP(Transmission Control Protocol)连接,操作系统默认TIME_WAIT的TCP连接回收时间是4分钟,TCP默认动态端口范围为开始端口49152,结束端口65535。这样会使回收TCP过慢导致系统吞吐量下降,甚至出现502访问失败问题。如何修改操作系统内核参数来缩短TIME_WAIT状态TCP连接回收时间和添加TCP动态端口范围,保证在大并发场景下操作系统的端口资源可用?

以Administrator用户登录Windows操作系统。修改TCP回收时间。
在Windows开始菜单中,单击“运行”输入“regedit”后按“Enter”打开注册表编辑器。
“HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters”路径。
在“编辑”菜单中,选择“新建 > DWORD (32-位)值”,输入名称“TcpTimedWaitDelay”。
右键单击TcpTimedWaitDelay,选择“修改”。在“编辑 DWORD(32位)值”对话框的“基数”区域中,选择十进制值为“30”,并“确定”。关闭注册表编辑器。

 

修改端口范围
在Windows开始菜单中,单击“运行”输入“cmd”
执行命令:netsh int ipv4 set dynamicportrange tcp startport=5000 numberofports=60000
重启操作系统。

 

实例:

最近线上遇到windows机器访问其他机器的时候失败的情况。实际就是本地的端口不够用造成的。


D:\>netsh interface ipv4 show dynamicportrange protocol=tcp


Protocol tcp Dynamic Port Range

---------------------------------

Start Port : 49152

Number of Ports : 16384


D:\>netsh interface ipv4 show tcpstats


MIB-II TCP Statistics

------------------------------------------------------

Timeout Algorithm: Van Jacobson's Algorithm

Minimum Timeout: 10

Maximum Timeout: 4294967295

Maximum Connections: Dynamic

Active Opens: 402947

Passive Opens: 989620

Attempts Failed: 122047

Established Resets: 49384

Currently Established: 135

In Segments: 47651175

Out Segments: 45510477

Retransmitted Segments: 465369

In Errors: 0

Out Resets: 65865

这个能用的端口实际就16384个,可以直接 netstat -atn查看一下每个状态的数量。如果对外做大量的请求会造成本地端口不够用。


可以修改一下起始端口:

netsh int ipv4 set dynamicport tcp start=2000 num=63000

netsh int ipv4 set dynamicport udp start=2000 num=63000

netsh int ipv6 set dynamicport tcp start=2000 num=63000

netsh int ipv6 set dynamicport udp start=2000 num=63000


然后修改一下注册表缩短time-wait的时间。

regedit打开注册表,添加

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

“MaxUserPort”=dword:0000fffe

“TcpTimeWaitDelay”=dword:0000005 (缩短为5秒)

 

=============linux系统====================

查看使用数量:netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'  

 

/etc/sysctl.conf文件的修改:

#对于一个新建连接,内核要发送多少个 SYN 连接请求才决定放弃,不应该大于255,默认值是5,对应于180秒左右时间  
net.ipv4.tcp_syn_retries=2 
#net.ipv4.tcp_synack_retries=2 
#表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为300秒 
net.ipv4.tcp_keepalive_time=1200 
net.ipv4.tcp_orphan_retries=3 
#表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间 
net.ipv4.tcp_fin_timeout=30   
#表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。 
net.ipv4.tcp_max_syn_backlog = 4096 
#表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭 
net.ipv4.tcp_syncookies = 1 
 
#表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭 
net.ipv4.tcp_tw_reuse = 1 
#表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭 
net.ipv4.tcp_tw_recycle = 1 
 
##减少超时前的探测次数  
net.ipv4.tcp_keepalive_probes=5  
##优化网络设备接收队列  
net.core.netdev_max_backlog=3000  

 

修改完之后执行/sbin/sysctl -p让参数生效。


这里头主要注意到的是

net.ipv4.tcp_tw_reuse
net.ipv4.tcp_tw_recycle

net.ipv4.tcp_fin_timeout

net.ipv4.tcp_keepalive_*

这几个参数。


net.ipv4.tcp_tw_reuse和net.ipv4.tcp_tw_recycle的开启都是为了回收处于TIME_WAIT状态的资源。

net.ipv4.tcp_fin_timeout这个时间可以减少在异常情况下服务器从FIN-WAIT-2转到TIME_WAIT的时间。

net.ipv4.tcp_keepalive_*一系列参数,是用来设置服务器检测连接存活的相关配置。


实例:

一天业务开发反馈说最近总是出现时不时连接数据库失败,PHP现在有时会报 连接数过多。返回too much connections....


排查

登录数据库服务器,第一时间直接查看tcp连接数:


[root@s0001-gz ~]# netstat -nalpt | grep 3306 |wc -l

9093

一看9000多个连接了,有点恐怖。

登录数据库服务查看实际连接数:


mySQL>show processlist;


....


468 rows


连接数才468个,而设置的max_connection=1000;


一半都达不到,那问题就肯定出在系统的连接数上了。


查看实际的连接用户:


90%全部是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 时间


查看结果:

image.png

如对本文有疑问,请提交到交流论坛,广大热心网友会为你解答!! 点击进入论坛


发表评论 (89人查看0条评论)
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
用户名: 验证码: 点击我更换图片
最新评论
------分隔线----------------------------