TIME_WAIT 的 Timer

Posted by qmsheng on December 19, 2017

我们知道 TCP 在关闭连接的时候,主动断开的一方将处于 TIME_WAIT 状态,并将持续两倍的 MSL。这个 MSL 在 RFC 793 中的建议是 1 分钟,但是很多系统实现都是 30 秒,所以 TIME_WAIT 的时长也就是 1 分钟。

而且这个数值是硬编码在内核中的,也就是说除非你重新编译内核,否则没法修改它。我们可以通过 ss 来查看 TIME_WAIT 的剩余存活时长(netstat 也可以 -o 参数)

可以看到上面标注的那个 TIME_WAIT 连接还可以存活 38s, 之后就会被系统回收掉。

另外,还能看到有一些 ms 级的连接,这是因为我在服务端开启了 TIME_WAIT 的快速回收,通过内核参数 net.ipv4.tcp_tw_recycle = 1。当开启了这个配置后,内核会快速的回收处于 TIME_WAIT 状态的连接。多快?不再是 2MSL,而是一个 RTO (retransmission timeout,数据包重传的 timeout 时间)的时间,这个时间是根据 RTT 动态计算出来,但是远小于 2MSL。在一个高性能的系统中,大概会稳定在 200ms 左右,可以通过「ss -int」命令来确认。

打开这个参数会有比较大的坑,可能会让 TCP 连接出一些诡异的问题,因为其违反了 TCP 协议(RFC 1122)

当然,TCP Timer 除了 TIME_WAIT 这种,还有 KEEPALIVE, ON, OFF 三种类型

  • KEEPALIVE 这里的 keepalive 可并不是长连接的意思,而是 TCP 的「保活」机制,这里不会介绍其细枝末节

  • ON 就是 RTO 超时重传时间

  • OFF 以上三种都不属于

上图是 Timer 后面各个数字的含义,就不再做过多的解释了。


赞赏是对作者最大的支持