简述 TCP 的 TIME_WAIT
xxxixxxx

为什么 TIME_WAIT

主动关闭连接的一方最终进入 TIME_WAIT 状态等待一段才真正的释放内核中的连接记录,在释放记录之前这个连接使用的本地端口将一直被占用。
保持一段时间的 TIME_WAIT 的理由是:担心 ack N+1 没有送达,导致被动方重传 FIN N,那么主动方应当再次响应 ack N+1
如果没有 TIME_WAIT 就直接复用该连接占用的端口,那么万一被动方重传FIN N,那么使用相同端口的新连接就会被错误关闭。
四次挥手

优化 TIME_WAIT

谁主动关闭 socket,谁TIME_WAIT
如果双方响应正常,TIME_WAIT 应该只是瞬间状态。

服务端主动关闭

无论有多少连接,服务端都只有一个端口,那就是监听端口,大量连接之间的差异仅仅是 TCP 4 元祖的客户端 ip 和 port 不同而已。

因此服务端TIME_WAIT压根不会耗尽端口,因为它就一个端口。

那么服务端就不需要优化了吗?对,没必要优化,一个TIME_WAIT的 4 元祖当遇到新的 SYN 时会复用,不需要特殊配置。

另外,当TIME_WAIT数量超过内核选项 net.ipv4.tcp_max_tw_buckets 的限制时,多余的TIME_WAIT连接将被立即关闭,然后在 netstat -s 中留下如下的溢出统计指标:

客户端主动关闭

客户端每个连接都会随机选择一个本地端口,所以最终会导致客户端大量端口处于 TIME_WAIT 状态,这和服务端主动关闭是最大的不同。
所以我们通常所说的 TIME_WAIT 问题都是针对客户端的,只是好像很少有人提及这一点。
网上有一种优化手段是把 net.ipv4.tcp_max_tw_buckets 调低,这样 TIME_WAIT 连接就会被删除,但是这不是一个最佳手段哈。

目前唯一安全的选项就是同时开启如下 2 个选项:

1
2
net.ipv4.tcp_timestamps=1(连接发起方和接收方都需要开启)
net.ipv4.tcp_tw_reuse=1(只影响连接发起方)

上述配置只影响连接发起方,也就是客户端,对服务端是无效的。
它的作用是向外发起连接的时候,可以复用 TIME_WAIT 的端口,但是有一个前提
该端口最后一次通讯时间距离当前系统时间>1 秒

摘录于 https://yuerblog.cc/2020/03/09/关于time_wait问题简述与优化/

  • Post title:简述 TCP 的 TIME_WAIT
  • Post author:xxxixxxx
  • Create time:2021-02-22 15:09:00
  • Post link:https://xxxixxx.github.io/2021/02/22/1000-019简述 TCP 的 TIME_WAIT/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.
 Comments