报错是这么冒出来的。CentOS 7.9 的机器上把 net.ipv4.tcp_tw_reuse 设成 1,TIME_WAIT 还是堆到两万多,端口复用看起来完全没起作用,sysctl 读出来确实是 1。

中间走过弯路,把「timestamps 没开,复用需要靠时间戳做 PAWS 校验」当成主因,改完现象没变。

这类报错背后常见的原因有几处,逐个排除就行。这个参数只影响主动发起连接的一方,服务端被动关闭的连接不适用。少数情况下是连接的四元组还在,内核判断复用不安全,直接跳过。

还有一种情况,sysctl 改的是当前命名空间,容器里的网络栈是另一份。

第一件事是看 TIME_WAIT 分布在哪些状态

ss -s && ss -tan state time-wait | wc -l

然后确认时间戳和复用参数都开着

sysctl net.ipv4.tcp_tw_reuse net.ipv4.tcp_timestamps

接着把参数写进持久化配置

printf 'net.ipv4.tcp_tw_reuse = 1\nnet.ipv4.tcp_timestamps = 1\n' > /etc/sysctl.d/99-net.conf && sysctl -p /etc/sysctl.d/99-net.conf

末了在客户端侧验证复用是否生效

ss -tan state time-wait '( dport = :80 )' | wc -l

别只看报错消失,验证要多做一步。客户端一侧的 TIME_WAIT 数量明显下降,新建连接不再报 Cannot assign requested address,服务端的连接曲线保持平稳。

提醒一点。tcp_tw_reuse 治的是客户端端口耗尽,服务端 TIME_WAIT 多要靠长连接和 keepalive 解决;不要开 tcp_tw_recycle,新内核已经移除。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。

作者 9823189