一次即时通讯项目TIME_WAIT过多引发的记录 - 简书
问题现象:
客户端接受用户咨询期间部分用户连接无故断开重连,导致分配到一个新的客服
问题排查
一、发现异常点
- 看到问题发生,第一时间想到去看服务器状态和监控的各项指标
经排查,系统各项基础指标如内存,CPU使用率等都在正常范围内 - 因为是连接断开的问题,所以在基础指标正常之后就想到去看TCP的连接状态信息,发现在ESTABLISHED只有不到200的情况下,TIME_WAIT的数量达到了6W左右的量,网上查了下发现这个比例是很不正常的,所以分析方向指向TCP连接的问题
二、分析为什么
- 分析TIME_WAIT状态产生的原因
TIME_WAIT产生于tcp连接的4次挥手阶段,并且产生在主动断开连接的一方
这里假设是客户端首先发起断开连接的请求,过程如下
a、客户端先发送FIN,进入FIN_WAIT1状态
b、服务端收到FIN,发送ACK,进入CLOSE_WAIT状态,客户端收到这个ACK,进入FIN_WAIT2状态
c、服务端发送FIN,进入LAST_ACK状态
d、客户端收到FIN,发送ACK,进入TIME_WAIT状态,服务端收到ACK,进入CLOSE状态
客户端TIME_WAIT持续2倍MSL时长,在linux体系中大概是60s,转换成CLOSE状态
注:MSL 是Maximum Segment Lifetime英文的缩写,中文可以译为“报文最大生存时间”,MSL指明TCP报文在Internet上最长生存时间,每个具体的TCP实现都必须选择一个确定的MSL值.RFC 1122建议是2分钟,但BSD传统实现采用了30秒.TIME_WAIT 状态最大保持时间是2 * MSL,也就是1-4分钟.在redhat和centos系统中MSL也是采用的30秒
借网上一张简单的图来说明下
TCP连接的4次挥手断开过程简易图
-
TIME_WAIT过多的影响
在socket的TIME_WAIT状态结束之前,该socket所占用的本地端口号将一直无法释放。高TCP并发并且采用短连接方式进行通讯的通讯系统在高并发高负载下运行一段时间后,就常常会出现做为客户端的程序无法向服务端建立新的socket连接的情况。此时用“netstat -tanlp”命令查看系统将会发现机器上存在大量处于TIME_WAIT状态的socket连接,并且占用大量的本地端口号。最后,当该机器上的可用本地端口号被占完(或者达到用户可使用的文件句柄上限),而旧的大量处于TIME_WAIT状态的socket尚未被系统回收时,就会出现无法向服务端创建新的socket连接的情况。此时系统几乎停转,空有再好的性能也发挥不出来。
注:这里涉及到一个服务器最多可以达到多少连接上限的问题,由于TCP的要素--四元组(源地址,源端口,目的地址,目的端口)中有一个不同就可以连接起新的连接,所以理论上一个服务器能接受的TCP连接数量貌似是无上限的(不考虑存储连接信息的表资源被用光和其他资源耗尽的情况)————这
作者:进击的胖达
链接:https://www.jianshu.com/p/a2938fc35573
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。