确认端口耗尽需三步:先查cat /proc/sys/net/ipv4/ip_local_port_range得可用范围,再用ss -tan state time-wait | wc -l看TIME_WAIT是否逼近上限,最后结合lsof -p $PID和ss -s验证连接行为;扩端口范围(如1024–65535)比启tcp_tw_reuse更安全,因后者依赖时间戳且服务端启用易致RST,而扩范围无副作用。

端口耗尽不是“连不上远端”,而是本机没端口可用了——bind: cannot assign requested address 就是它最直白的报错。
怎么确认是本地临时端口真用完了?
先看系统允许用哪些端口:
cat /proc/sys/net/ipv4/ip_local_port_range 输出类似 32768 60999,说明可用端口约 28k 个。
再看当前 TIME_WAIT 连接数是否逼近这个值:
ss -tan state time-wait | wc -l
如果结果接近或超过 25k,且你的应用还在高频建连(比如每秒几十上百次 outbound),基本可以锁定是端口耗尽。
顺手验证下进程行为:
-
lsof -p $PID -nP | grep TCP | head -20看是不是大量-> X.X.X.X:Y的 outbound 连接,且本地端口列(第四列)在快速滚动变化 - 再跑一遍
ss -s,重点看timewait和orphaned是否持续增长,而established却不高
为什么扩端口范围比调 tcp_tw_reuse 更安全?
tcp_tw_reuse 只对客户端有效,但依赖 net.ipv4.tcp_timestamps=1,且服务端启用可能引发 RST;而扩大端口范围是直接增加资源池,无副作用。
操作很简单:
echo "1024 65535" > /proc/sys/net/ipv4/ip_local_port_range
注意两点:
- 别把起始设成
1或1024以下——这些端口常被特权服务占用,冲突风险高 - 写完记得持久化:
echo 'net.ipv4.ip_local_port_range = 1024 65535' >> /etc/sysctl.conf && sysctl -p
排查时容易漏掉的三个点
第一,ulimit -n 限制的是文件描述符总数,不是端口数,但它会卡在更前面:如果进程 FD 已满,连 socket() 都失败,根本走不到 bind 阶段。
第二,Docker 容器默认共享宿主机的 ip_local_port_range,但容器内进程看到的 /proc/sys/... 是隔离视图,得进容器里查,或统一在宿主机调。
第三,NAT 网关或云厂商 SLB 的连接跟踪表(conntrack)也可能提前打满,表现为客户端能连上、但很快断开或超时,此时 cat /proc/sys/net/netfilter/nf_conntrack_count 接近 nf_conntrack_max 就要怀疑它。
真正卡住的点,往往不在 TCP 参数本身,而在端口资源和连接生命周期管理的交界处。


















