先看现象。阿里云 ECS 上 CentOS 7.9,为了压 TIME_WAIT 把 tcp_fin_timeout 从 60 调到 10,之后客户端偶发连接被重置,ss 里 FIN-WAIT-2 的数量忽高忽低。

真正麻烦的地方在于,几个原因的现象几乎一样。tcp_fin_timeout 管的是 FIN-WAIT-2 的保持时间,和 TIME_WAIT 无关。也可能是对端还没发 FIN,本地提前回收套接字,之后到达的数据只能回 RST。

不容易想到的是,应用是短连接,关闭时没等对方确认,缩短超时把问题放大。

还有一种情况,中间设备的状态超时比 10 秒还长,连接被提前清掉。

先确认连接卡在哪个状态

ss -tan state fin-wait-2 | head -10 && ss -s | head -5

恢复默认值再看 RST 是否消失

sysctl -w net.ipv4.tcp_fin_timeout=60

接着统计 TIME_WAIT 实际有多少

ss -tan state time-wait | wc -l

末了用 tcp_tw_reuse 代替压超时

sysctl -w net.ipv4.tcp_tw_reuse=1

隔了一天再看,现象没变,说明不是偶发。

怎么算真的好了,看的是同一批现象。ss -s 里 FIN-WAIT-2 降到个位数,客户端不再出现连接重置,TIME_WAIT 稳定在两万以内。

tcp_fin_timeout 和 TIME_WAIT 没关系,想加速复用得靠 tcp_tw_reuse;调小它只会让半关闭的连接被提前砍掉。同一份配置在测试环境跑通,不代表线上没事,两边的默认值经常不一样。

作者 9823189