Appearance
tcpTIMEWAIT
回顾 TCP 四次挥手:正常情况下服务端收到了
ACK消息并关闭当前 TCP 连接,客户端等待msl 查看 cat /proc/sys/net/ipv4/tcp_fin_timeout2msl(Maximum Segment Lifetime) 进入 CLOSED。

从上述过程中,我们会发现 TIME_WAIT 仅在主动断开连接的一方出现,被动断开连接的一方会直接进入 CLOSED 状态,进入 TIME_WAIT 的客户端需要等待 2 MSL 才可以真正关闭连接。
一、没有 TIME_WAIT、或 TIME_WAIT 时间过短的问题
防止延迟的数据段被其他使用相同源地址、源端口、目的地址以及目的端口的 TCP 连接收到;
场景1:由于丢包(客户端发送的
ACK丢失),服务端没有收到ACK消息,服务器重新发送FIN关闭连接并等待新的ACK消息。如果没有 TIME_WAIT、或 TIME_WAIT 时间过短客户端无法收到重传的FIN包导致四次挥手服务优雅的完成。
场景2:假设刚好客户端以相同端口发送
SYN,那么服务器端就会返回RST。
场景3:由于 TIME_WAIT 过短,客户端用之前的端口新建 session。客户端收到了上个会话服务端延时的数据包。

三、解决 TIME_WAIT 过多新会话无法建立
- 使用
SO_LINGER选项并设置暂存时间l_linger为 0,在这时如果我们关闭 TCP 连接,内核就会直接丢弃缓冲区中的全部数据并向服务端发送RST消息直接终止当前的连接。 - 使用
net.ipv4.tcp_tw_reuse选项,通过 TCP 的时间戳选项允许内核重用处于TIME_WAIT状态的 TCP 连接。 - 修改
net.ipv4.ip_local_port_range选项中的可用端口范围,增加可同时存在的 TCP 连接数上限 - TCP 配置项
net.ipv4.tcp_tw_recycle已经在 Linux 4.12 中移除,所以我们不能再通过该配置解决TIME_WAIT设计带来的问题。