TCP TIME_WAIT 过多导致端口耗尽的排查与调优

举报
1swei 发表于 2026/11/09 08:59:20 2026/11/09
【摘要】 现象一台高并发短连接服务(反向代理、压测客户端、批量调用方)运行一段时间后,新建连接开始失败,报错 Cannot assign requested address,但 CPU、内存、带宽都不高,服务端也没有拒绝连接。这时很可能不是对端的问题,而是本机可用的临时端口被 TIME_WAIT 状态的连接占满了。 什么是 TIME_WAITTCP 主动关闭连接的一方,在发送最后一个 ACK 后会进...

现象

一台高并发短连接服务(反向代理、压测客户端、批量调用方)运行一段时间后,新建连接开始失败,报错 Cannot assign requested address,但 CPU、内存、带宽都不高,服务端也没有拒绝连接。这时很可能不是对端的问题,而是本机可用的临时端口被 TIME_WAIT 状态的连接占满了。

什么是 TIME_WAIT

TCP 主动关闭连接的一方,在发送最后一个 ACK 后会进入 TIME_WAIT 状态,持续 2MSL(Linux 默认约 60 秒),目的是防止旧连接的延迟报文干扰新连接。在这段时间内,该连接的四元组(源 IP、源端口、目标 IP、目标端口)不能被复用。短连接场景下,每秒新建几千个连接,60 秒就能攒下几万个 TIME_WAIT,而临时端口默认只有约 2.8 万个,很快耗尽。

第一步:确认数量

先看总体分布,再看 TIME_WAIT 数量:

ss -s

ss -tan state time-wait | wc -l

ss -tan | awk '{print $1}' | sort | uniq -c | sort -nr

再看本机临时端口范围和超时时间:

cat /proc/sys/net/ipv4/ip_local_port_range

cat /proc/sys/net/ipv4/tcp_fin_timeout

cat /proc/sys/net/ipv4/tcp_max_tw_buckets

如果 TIME_WAIT 数量接近端口范围上限,基本可以确认是端口耗尽;如果数量不大,就要换方向排查,比如文件描述符、连接数上限或对端限流。

第二步:调优参数(先在测试环境验证)

把下面几项写入 /etc/sysctl.conf,再执行 sysctl -p 生效:

net.ipv4.tcp_tw_reuse = 1

net.ipv4.tcp_fin_timeout = 30

net.ipv4.ip_local_port_range = 10240 65535

net.ipv4.tcp_max_tw_buckets = 262144

说明三点:第一,tcp_tw_reuse 只对作为客户端主动发起连接的一方有效,且不要在 NAT 环境下随意开启;第二,tcp_fin_timeout 缩短的是 FIN_WAIT2 的等待时间,间接减少堆积;第三,tcp_tw_recycle 已在 Linux 4.12 及之后内核中移除,网上老教程里的这一项不要再加。

第三步:根治要靠减少短连接

参数调优只是争取时间,根治办法是减少新建连接的频率:客户端使用连接池和长连接,复用已有连接;反向代理开启 keep-alive;调用方避免每次请求都新建连接;必要时用多个出口 IP 分摊端口压力。做完后重新跑 ss -tan state time-wait | wc -l 观察,数量应明显回落且不再随时间单调上涨。

小结

排查顺序是:先用 ss -s 和 ss -tan state time-wait | wc -l 确认 TIME_WAIT 规模,再核对 /proc/sys/net/ipv4/ip_local_port_range,最后才是调参和改造连接复用。记住,TIME_WAIT 本身是 TCP 的正常保护机制,调参的目标是让它不再成为瓶颈,而不是把它彻底关掉。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。