TCP状态—TIME_WAIT—学习记录

380 阅读4分钟

TCP状态转换图

根据上图可以看到TIME_WAIT是主动关闭TCP连接一端出现的状态,该端点停留在这个状态的持续时间是TCP分段(IP报文)可以存在于互联网系统中的最大时间(maximum segment lifetime)的两倍,一般描述为2MSL;

                                                        借用网上图片

可以看以上两张图,在主动关闭一方收到被动关闭一方最终的FIN消息之后就会进入TIME_WAIT状态,经过发送最后的ACK消息、等待2MSl后会进入到CLOSED状态。

正常流程:
1、客户端没有待发送的数据时,它会向服务端发送FIN消息,发送消息后会进入FIN_WAIT_1状态;

2、服务端接收到客户端的FIN消息后,会进入CLOSE_WAIT状态并向客户端发送ACK消息,客户端接收到
ACK消息时会进入FIN_WAIT_2状态;

3、当服务端没有待发送的数据时,服务端会向客户端发送FIN消息,然后进入LAST_ACK状态;

4、客户端接收到FIN消息后,会进入TIME_WAIT状态并向服务端发送ACK消息,服务端收到后会进入CLOSED
状态,经过2MSL后客户端也会进入CLOSED状态

TIME_WAIT存在的理由

  • 可靠的实现TCP全双工连接的终止,保证TCP连接的远程被正确关闭,即等待被动关闭连接的一方收到FIN对应的 ACK 消息;

  • 允许老的重复的分节在网络中消逝,防止延迟的数据段被其他使用相同源地址、源端口、目的地址以及目的端口的TCP(简单理解就是新的TCP连接)连接收到;

TIME_WAIT时长(2MSL)如何确定的?

首先MSL表示一个TCP分段(IP报文)可以存在于互联网系统中的最大时间,由TCP的实现,超出这个时间的消息分片都会被丢弃, 

一般系统设置,可以根据需要自行调整 
[root@~]$cat /proc/sys/net/ipv4/tcp_fin_timeout 
60

为什么TIME_WAIT需要2MSL呢?TIME_WAIT状态由主动关闭的A来保持,那么我们来考虑对于A来说,可能接到一个连接的数据包的最大时长:【A刚发出的数据包,能保持MSL时长的寿命,它到了B端后,B端由于关闭连接了,会响应RST包,这个RST包最长也会在 MSL 时长后到达A,那么A端只要保持2MSL就能保证网络中这个连接的包都会消失】。

简单分析存在的理由
// 保证TCP正常关闭
如果客户端等待的时间不够长,当服务端还没有收到ACK消息时,客户端就重新与服务端建立TCP连接就会
造成服务端因为没有收到ACK消息,仍然认为当前连接是合法的,客户端重新发送SYN消息请求握手时会收
到服务端的RST包,建立连接的过程就会被终止,出现连接未正常关闭,导致无法创建新的连接。

// 保证旧的消息不被新的连接所处理
[root@~]$sysctl net.ipv4.ip_local_port_range
net.ipv4.ip_local_port_range = 32768	60999
[root@~]$cat /proc/sys/net/ipv4/ip_local_port_range
32768	60999

客户端可以使用的端口号(可以更改系统设置)60999-32768=28231,也就说可以使用的端口号仅为28231
个,但是如果主机在过去一段时间内与目标主机的特定端口创建的TCP连接数超过28231,那么再创建新
的TCP连接就会发生错误,也就是说如果我们不调整主机的配置,那么每秒能够建立的最大TCP连接数为
~=470;当我们请求建立连接数>470时就要复用原有端口号,如果没有正常关闭原有TCP连接,或者关闭的
连接还有未完成的消息传递,就会出现旧的消息在新创建的连接中出现。

总结:

TCP协议中TIME_WAIT状态存在的原因,简单理解就是因为TCP是一个可靠、稳定的连接协议,为了防患于未然,应对一些TCP连接状态的异常情况,添加的一种状态;能保证连接的正常关闭和消息的正常消逝。

TIME_WAIT过多怎么办?

由上面的理解,可以知道TIME_WAIT主要是主动关闭TCP连接的一方出现的状态;如果在高并发,建立大量短连接的场景就会出现大量TIME_WAIT状态,而TIME_WAIT为了保证链接正常关闭,会保持2MSl,这时候就会造成资源的浪费;

一般解决方案是两个方向

1、修改系统设置,缩短TIME_WAIT时长

2、可以看看当前业务场景是否适合长连接

本人踩坑的案例分析

“socket: too many open files, Attempt 1 ”

在做接口压测时候出现了以上问题,主要场景是请求后端接口,使用短连接每次发送请求都创建新的TCP连接,当高并发到一定数量问题就会出现,经过多次方案讨论,代码调整,修改为长连接解决了以上问题,使用TCP复用连接功能,减少频道的创建、销毁TCP带来的消耗;每个人的业务场景不同,具体问题还需要具体分析。

相关概念

全双工(Full Duplex)是通讯传输的一个术语;通信允许数据在两个方向上同时传输,它在能力上相当于两个单工通信方式的结合。全双工指可以同时(瞬时)进行信号的双向传输(A→B且B→A);指A→B的同时B→A,是瞬时同步的。 

单工就是在只允许A方向B方传送信息,而B不能向A传送 。

MSL是任何IP数据报能够在因特网中存活的最长时间。

参考