首页/系统/Linux 内核与性能调优速查/net.ipv4.tcp_tw_reuse TIME_WAIT 复用
sysctl 内核参数72 条

net.ipv4.tcp_tw_reuse TIME_WAIT 复用

允许把处于 TIME_WAIT 的套接字在协议安全前提下复用于新的出站连接(依赖时间戳);只对客户端方向的连接有效。

tcp_tw_reuse 是什么

net.ipv4.tcp_tw_reuse 允许本机作为客户端发起新连接时,在协议层面确认安全的前提下复用一个尚处于 TIME_WAIT 状态的本地端口。TIME_WAIT 是主动关闭方必须持有的状态,Linux 上固定约 60 秒(2MSL),短连接密集时大量端口被占住。开启复用的价值在于让出站短连接不必干等端口释放,代价是依赖 TCP 时间戳做旧报文判别。它只作用于本机主动发起的连接,对服务端被动关闭留下的 TIME_WAIT 无效。

基本信息

参数net.ipv4.tcp_tw_reuse
取值0 关闭 / 1 允许复用 / 2 仅本机回环流量复用,较新内核可能作为默认值,以回读为准
依赖参数net.ipv4.tcp_timestamps 必须为 1
作用方向仅本机主动发起的出站连接
TIME_WAIT 时长约 60 秒,Linux 未提供配置项
配套参数net.ipv4.tcp_max_tw_buckets 限制总量,net.ipv4.ip_local_port_range 决定端口池大小

典型使用场景

  • 出站短连接密集的服务:网关、代理、爬虫、调用第三方接口的客户端易报 Cannot assign requested address
  • 压测机与被压端同为短连接:本地端口周转不过来时,先确认方向再考虑是否复用
  • 排查端口耗尽:用 ss -s 与状态统计区分是端口池太小还是 TIME_WAIT 堆积太多
  • 跨机房调用优化:确认端口复用不是唯一手段后,与连接池、长连接复用一起评估
  • 回归验证:调整后持续观察 TIME_WAIT 数量与新建连接的失败率变化

查看与调整

查看与调整
sysctl net.ipv4.tcp_tw_reuse net.ipv4.tcp_timestamps   # 复用开关与时间戳依赖
ss -tan state time-wait | wc -l                        # 当前 TIME_WAIT 总数
ss -s | head                                           # 各状态汇总计数
sysctl -w net.ipv4.tcp_tw_reuse=1                      # 临时开启复用
sysctl net.ipv4.ip_local_port_range                    # 确认出站端口池大小
sysctl net.ipv4.tcp_max_tw_buckets                     # 确认 TIME_WAIT 总量上限

判断是客户端还是服务端在堆积

判断是客户端还是服务端在堆积
ss -tan state time-wait | awk '{print $4}' | awk -F: '{print $NF}' | sort | uniq -c | sort -rn | head   # 本地端口分布
ss -tan state time-wait | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c | sort -rn | head   # 对端分布
# 本地端口集中在高位区间说明是出站连接留下的 TIME_WAIT,此时复用才可能有帮助

相关指标读法

观察点含义正常与异常
TIME_WAIT 数量本机当前处于该状态的套接字数数万条本身不是故障,要看是否伴随端口耗尽
Cannot assign requested address建连时本地端口无可用出现即要处理:扩端口池、改长连接或开复用
tcp_timestamps复用判定的前置条件为 0 时复用条件不成立,开了也难见效果
tcp_max_tw_buckets 溢出日志dmesg 出现 time wait bucket table overflow说明总量触顶,处理方向与端口复用不同
它解决不了服务端方向的 TIME_WAIT。服务端在主动关闭连接后持有 TIME_WAIT 属于协议正确行为,常见处理方向是改用长连接与连接池、让客户端先关闭、或在四层网关前置做连接复用,而不是改这个参数。
旧资料里常与它并列出现的 net.ipv4.tcp_tw_recycle 已在 Linux 4.12 起从内核移除:该选项依赖时间戳丢弃「看起来过期」的报文,在 NAT 后的客户端上会造成随机连接失败,属于应当废弃的做法,不要再照抄。
复用依赖时间戳判别旧报文,因此会顺带改变对外表现:极少数老旧中间设备对 TCP 时间戳处理异常时可能引起连接问题。若链路上有此类设备,先在小范围验证再推广,而不是一次性全量开启。
有些资料建议用应用侧 SO_LINGER 置 0 强制发 RST 关闭连接来消灭 TIME_WAIT,这会跳过正常四次挥手、已入发送队列的数据可能被直接丢弃,属于危险做法,不应作为常规优化手段推广。

易错点

  • 把它当作 TIME_WAIT 的通用解药:先确认套接字方向和连接发起模式,服务端堆积的情况改了也没用
  • 同时把 tcp_timestamps 关掉:复用条件不再成立,等于开了个无效开关,两个参数必须一起看
  • 误信旧方案启用 tcp_tw_recycle:该参数在内核 4.12 已移除,遗留脚本里的写入会报错或静默失败
  • 看到 TIME_WAIT 上万条就立刻调参:数量本身不等于故障,先确认是否有端口耗尽和建连失败
  • 改完不落盘也不做基线对比:重启后行为回退,出站连接失败率在高峰期再次抬头却找不到原因

数据来源与参考

  • Linux 内核 Documentation/admin-guide/sysctl/net.rst
  • man 7 tcp(TIME-WAIT 与时间戳)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌