大家好,关于终于搞懂了服务器为啥产生大量的TIME_WAIT!-服务器出现大量time_wait很多朋友都还不太明白,今天小编就来为大家分享关于的知识,希望对各位有所帮助!
[[426935]]
我一开始就写这个。大约4年前,听一位运维同学提到TIME_WAIT状态下TCP连接数过多的问题,但当时并没有详细思考。最近听有人提到有一个新手在压测的时候遇到了这个问题。问题,所以花一些时间详细研究一下。
从这几个方面入手:
问题描述:什么现象?有什么影响?
问题分析
解决方案
基本原则
问题描述
模拟高并发场景,会出现批量TIME_WAIT TCP连接:
过了一小段时间,所有TIME_WAIT都消失并被回收,端口和服务都正常了。
即在高并发场景下,存在TIME_WAIT连接,这是正常现象。
线上场景、持续高并发场景
部分TIME_WAIT连接被回收,但又产生新的TIME_WAIT连接;
在某些极端情况下,可能会出现大量TIME_WAIT连接。
思考:
上面提到的大量TIME_WAIT状态TCP连接对业务有影响吗?
Nginx作为反向代理时,大量的短链接可能会导致Nginx上的TCP连接处于time_wait状态:
每个time_wait状态都会占用一个“本地端口”,上限为65535(16位,2字节);
当大量连接处于time_wait时,新建立TCP连接时会出错,地址已在使用中: connect异常
TCP连接状态统计:
//统计:各种连接数$netstat -n|awk'/^tcp/{++S[$NF]}END{for(ainS)printa,S[a]}'ESTABLISHED1154TIME_WAIT1645提示:TCP本地端口数,上限为65535(6.5w)。这是因为TCP头使用16位来存储“端口号”,所以上限是65535。
问题分析
存在大量处于TIME_WAIT 状态的TCP 连接。其本质原因是什么?
存在大量短连接
特别是在HTTP请求中,如果连接头值设置为close,那么“服务器”基本上会发起主动关闭连接。
但在TCP四路挥手关闭机制中,为了保证ACK重传并丢弃延迟数据,将time_wait设置为MSL(最大数据包生存时间)的2倍
TIME_WAIT状态:
在TCP连接中,当一方主动关闭连接时出现该状态; (收到FIN命令后,进入TIME_WAIT状态,并返回ACK命令)
保持2 MSL次,即4分钟; (MSL 为2 分钟)
解决办法
解决上述time_wait状态大量存在,导致创建新连接失败的问题。一般的解决方案是:
在客户端,在HTTP请求的标头中,将连接设置为keep-alive以使其保持活动状态一段时间:这在当前的浏览器中通常是这样做的。
服务器端
允许重用处于time_wait状态的套接字
减少time_wait时间,设置为1 MSL(即2分钟)
结论:几个核心要点
time_wait状态的影响:
在TCP连接中,“主动发起关闭连接”的一端会进入time_wait状态。
time_wait状态,默认会持续2MSL(消息最大存活时间),通常为2x2分钟
在time_wait状态下,TCP连接占用的端口不能再次使用。
TCP端口数,上限6.5w(65535,16位)
大量存在time_wait状态,在创建新的TCP连接时会出现错误,地址已经在使用中: 连接异常
现实场景
服务器端,常规设置:不允许“主动关闭连接”
然而,在HTTP请求中,http头连接参数可能会被设置为close。然后,服务器处理完请求后会主动关闭TCP连接。
目前的浏览器中,HTTP请求连接参数一般设置为keep-alive。
在Nginx反向代理场景中,可能会出现大量的短链接。在服务器端,可能有
解决办法
服务器端,
允许重用处于time_wait状态的套接字
减少time_wait时间,设置为1 MSL(即2分钟)
附录
几个方面:
TCP连接状态查询
MSL时间
TCP三路握手和四路握手
附录 A:查询 TCP 连接状态
Mac下,查询TCP连接状态的具体命令:
//Mac下,查询TCP连接状态$netstat-nat|grepTIME_WAIT //Mac下,查询TCP连接状态,其中-E表示grep或$netstat-nat|grep-E'TIME_WAIT|LocalAddress'的匹配逻辑ProtoRecv-QSend -QLocalAddressForeignAddress(state)tcp400127.0.0.1.1080127.0.0.1.59061TIME_WAIT//统计:各种连接数$netstat -n|awk'/^tcp/{++S[$NF]}END{for( ainS) printa,S[a]}'ESTABLISHED1154TIME_WAIT1645
附录 B:MSL 时间
MSL, 最大分段生命周期, "消息的最大分段生命周期",
任何数据包在网络上存在的最长时间。超过这个时间的消息将被丢弃。 (IP消息)
TCP报文(段)是ip数据报(数据报)的数据部分。
尖端:
RFC 793规定MSL为2分钟。实际应用中,常用30秒、1分钟、2分钟。
2MSL,TCP的TIME_WAIT状态,也称为2MSL等待状态:
当TCP一端发起主动关闭(收到FIN请求)时,发送最后一次ACK响应后,即第三次握手完成后,发送第四次握手的ACK包后,进入TIME_WAIT状态。
您必须保持此状态两倍的MSL 时间。等待2MSL时间的主要目的是防止对方收不到最后一个ACK包。那么对方会在超时后重发第三次握手的FIN包,并主动关闭终端重发。在FIN数据包之后,可以发送ACK响应数据包。
在TIME_WAIT状态下,两端的端口都无法使用。它们必须等到2MSL时间结束才可以继续使用。 (IP层)
当连接处于2MSL 等待阶段时,任何迟到的报文段都将被丢弃。
但在实际应用中,可以设置“SO_REUSEADDR选项”来使用占用的端口,而无需等待2MSL时间到期。
附录C:TCP三路握手和四路握手,详细参考:TCP三路握手和四路挥手
具体图:
三次握手,建立连接过程
挥手四次释放连接进程
几个核心问题:
time_wait 是「服务器端」的状态?or 「客户端」的状态?
RE: time_wait 是“主动关闭TCP 连接”一方的状态,可能是“客户端”或“服务器端”
一般情况下是“客户端”的状态; “服务器”一般设置为“不主动关闭连接”
服务器在对外服务时,是「客户端」发起的断开连接?还是「服务器」发起的断开连接?
正常情况下,断开是由“客户端”发起的
“服务器”一般设置为“不主动关闭连接”,服务器通常执行“被动关闭”
然而,在HTTP请求中,http头连接参数可能会被设置为close。然后,服务器处理完请求后会主动关闭TCP连接。
关于HTTP请求中主动关闭TCP连接的机制:TIME_WAIT只有在主动断开后才会出现,那么主动断开的一方是服务器?
答案是肯定的。在HTTP1.1协议中,有一个Connection头。连接有两个值:close 和keep-alive。这个头相当于客户端在完成请求后告诉服务器是关闭连接还是保持连接。保持连接是指在保持连接期间,客户端只能主动断开连接。还有一个keep-alive header,设置的值代表服务器保持连接的时间。
HTTP默认的Connection值是close,这意味着关闭请求的一方几乎都是由服务器发起的。那么服务器产生过多的TIME_WAIT也是正常的。
虽然默认的HTTP Connection值是close,但是当前的浏览器在发送请求时一般都会将Connection设置为keep-alive。所以有人说没必要调整参数来减少TIME_WAIT。
关于 time_wait:
TCP连接建立后,“主动关闭连接”的一端收到对方的FIN请求后发送ACK响应,会处于time_wait状态;
time_wait状态,存在的必要性:
可靠地实现TCP全双工连接的终止:在四次挥手关闭TCP连接的过程中,最后一个ACK是由“主动关闭连接”的一端发送的。如果这个ACK丢失,对方就会重新发送FIN请求,所以,在“主动关闭连接”一节中,需要维护一个time_wait状态来处理对方重新发送的FIN请求;
延迟到达数据包的处理:由于路由器可能存在抖动,TCP数据包将延迟到达。为了防止“TCP数据包延迟到达”被误认为是“新TCP连接”的数据,需要允许新创建的TCP连接。此前,它保持不可用状态并等待所有延迟数据包消失。一般设置为MSL(数据包最大生存时间)的2倍,以解决“TCP数据包延迟”问题;
好了,文章到此结束,希望可以帮助到大家。
本文采摘于网络,不代表本站立场,转载联系作者并注明出处:https://www.iotsj.com//kuaixun/7109.html
用户评论
我也是最近才发现自己服务器的时间等待状态好多啊,还好现在明白了原因。
有14位网友表示赞同!
这篇文章讲得真清晰!我现在可以理解为什么我的服务器会一直有TIME_WAIT状态了。
有19位网友表示赞同!
终于知道为啥我之前那些网站总是慢悠悠的,原来是TIME_WAIT太多了啊!
有18位网友表示赞同!
看来我们很多程序员都在遇到这个问题呢,感谢作者分享这个知识点!
有8位网友表示赞同!
这篇文章让我对服务器管理有了更深入的了解,非常实用!
有6位网友表示赞同!
以前一直以为TIME_WAIT就是系统的一个bug,原来它还有这么重要的作用啊。
有7位网友表示赞同!
学习了,下次遇到这种情况就知道应该如何处理了!
有19位网友表示赞同!
这篇文章让我对TCP/IP协议有了更清晰的认识。
有6位网友表示赞同!
我打算去研究一下怎么优化TIME_WAIT的状态,希望能提升服务器效率!
有13位网友表示赞同!
感谢作者的科普文章,非常详细!
有11位网友表示赞同!
以前都没太明白TIME_WAIT到底是怎么回事儿了,现在终于明白了!
有10位网友表示赞同!
原来这只是一些网络安全机制的体现,还挺有意思的。
有8位网友表示赞同!
我的服务器总是出现TIME_WAIT状态,看来我要好好学习一下这篇文章了!
有12位网友表示赞同!
很高兴找到解决这个问题的文章,真是太及时啦!
有7位网友表示赞同!
希望以后遇到类似问题,也能像这次一样找到合适的解决方案!
有8位网友表示赞同!
文章写的真好啊,很容易理解!
有11位网友表示赞同!
终于不用再困惑了,感谢作者的解答!
有8位网友表示赞同!
这篇文章解决了我的一个困扰!
有8位网友表示赞同!
我打算把这篇文章分享给我的朋友们!
有5位网友表示赞同!
这真是个很棒的文章!
有7位网友表示赞同!