
为什么 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 | net.ipv4.tcp_timestamps=1(连接发起方和接收方都需要开启) |
上述配置只影响连接发起方,也就是客户端,对服务端是无效的。
它的作用是向外发起连接的时候,可以复用 TIME_WAIT 的端口,但是有一个前提
该端口最后一次通讯时间距离当前系统时间>1 秒
- 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.