端口耗尽的来龙去脉
应用偶发报出无法分配地址的错误,很多时候不是目标不通,而是本机临时端口用光了。一条 TCP 连接由源地址、源端口、目的地址、目的端口四元组唯一标识,因此本机到同一个目标地址与端口的连接数,上限就是可用临时端口的数量。大量短连接不复用、主动关闭后又停留在等待状态,几分钟就能把端口池耗尽,报错看起来却像网络不通。
基本信息
| 典型报错 | 无法分配请求的地址(EADDRNOTAVAIL) |
|---|---|
| 根因 | 到同一目标的四元组用尽可用临时端口 |
| 高发场景 | NAT 网关、压测客户端、爬虫、出口地址少而连接多 |
| 排查方向 | 连接数统计、等待状态堆积、连接池复用情况 |
| 相关资源 | 临时端口范围、连接跟踪表容量 |
典型使用场景
- 压测客户端连接失败:区分是目标限流还是本机端口用尽
- 网关异常:并发访问同一后端时出口连接数上不去
- 爬虫服务中断:短连接模式下运行一段时间后集中报错
- 监控告警联动:连接跟踪表打满时同步出现丢包日志
- 架构评审:评估是否需要增加出口地址或改用长连接
现象与根因对照
| 现象 | 可能根因 | 验证方式 |
|---|---|---|
| 集中报地址不可用 | 临时端口耗尽 | 统计各状态连接数与端口范围 |
| 等待状态数量巨大 | 短连接不复用 | 按状态统计连接数 |
| 伴随丢包日志 | 连接跟踪表打满 | 查看内核日志与表容量 |
| 仅对特定目标失败 | 到该目标的四元组受限 | 按目的地址分组统计 |
诊断命令
诊断命令
# 总览:各类连接状态与套接字统计
ss -s
# 统计等待关闭状态的连接数量
ss -tan state time-wait | wc -l
# 统计到某个目标的已建立连接数
ss -tan state established '( dport = :443 )' | wc -l
# 查看临时端口范围,判断上限量级
sysctl net.ipv4.ip_local_port_range同一目标可用连接数的上限约等于临时端口总数:Linux 默认范围约两万八千个端口,放宽后用满全范围也只有六万多个。因此高并发场景下,出口地址数量与连接复用策略往往比调内核参数更有效。
把等待状态强行缩短或启用某些已被移除的参数,可能带来连接错乱与静默失败,尤其在经过 NAT 的环境里风险更高。优先修连接池与短连接模型,再考虑参数调整。
处置顺序
- 先统计连接状态分布,确认是否真是端口耗尽
- 再核对应用是否启用了连接复用与长连接
- 然后评估增加出口地址或分散目标地址
- 最后才考虑调整内核参数,并做好回退方案