TCP 端口耗尽是什么?为什么大量短连接会导致无法建立新连接?
简化版
客户端主动发起 TCP 连接时,需要占用一个本地临时端口。连接由四元组 (源IP, 源端口, 目标IP, 目标端口) 唯一标识。大量短连接、连接未复用、TIME_WAIT 堆积或连接泄漏,都可能让临时端口耗尽,导致新连接失败。优化方向包括连接池、长连接、扩大端口范围、降低 TIME_WAIT 压力和提升连接复用。
详细版
端口耗尽常见于客户端或网关:
同一源 IP -> 同一目标 IP:Port
可用并发连接数受临时端口范围和 TIME_WAIT 回收影响
如果每个请求都新建连接,请求结束后主动关闭方进入 TIME_WAIT,端口短时间不能安全复用。高并发下端口池被占满,就会出现 Cannot assign requested address、连接超时或建连失败。
完整版教学
一、TCP 连接由什么唯一标识
TCP 连接不是只看目标端口,而是由四元组标识:
源 IP
源端口
目标 IP
目标端口
同一个客户端访问同一个服务端地址时,目标 IP 和目标端口固定,可变化的主要是本地临时端口。
二、临时端口为什么有限
客户端发起连接时,操作系统会从临时端口范围中分配一个源端口。这个范围不是无限的。
| 因素 | 影响 |
|---|---|
| 临时端口范围 | 决定可用源端口池大小 |
| 目标地址数量 | 目标越多,四元组组合越多 |
| TIME_WAIT 时长 | 端口释放变慢 |
| 连接复用 | 复用越好,新端口消耗越少 |
关键点:端口耗尽常出现在“同一源 IP 高频访问同一目标”的短连接场景。
三、TIME_WAIT 为什么会加剧问题
主动关闭连接的一方通常进入 TIME_WAIT,等待一段时间以确保旧报文过期、对端能收到最后 ACK。
短连接越多
TIME_WAIT 越多
临时端口越久不能重新用于相同四元组
如果请求速率超过端口回收能力,就会耗尽。
四、常见现象
线上可能看到:
Cannot assign requested address
connect timeout
大量 TIME_WAIT
连接池命中率低
NAT 网关端口不足
在容器、代理、NAT 网关里,这个问题更常见,因为很多实例可能共享少量出口 IP。
五、如何优化
优先从连接复用入手:
HTTP keep-alive
连接池
HTTP/2 多路复用
减少不必要短连接
系统层可以扩大临时端口范围、调优 TIME_WAIT 相关参数,但要理解风险,不能无脑缩短。
六、NAT 场景为什么更明显
多个内网客户端通过同一个 NAT 出口访问同一个外部服务时,公网侧可用四元组可能集中在一个出口 IP 上。NAT 设备也要维护端口映射,映射表和端口范围都可能成为瓶颈。
很多客户端 -> 一个 NAT IP -> 同一个目标服务
这时扩容出口 IP、分散目标、提高连接复用都可能有效。
七、常见误区与追问
- 误区:只有服务器监听端口会耗尽。 客户端临时端口也会耗尽。
- 误区:TIME_WAIT 都是坏的,应该立刻清掉。 TIME_WAIT 有协议安全意义,调参要谨慎。
- 误区:增加线程数能解决端口耗尽。 端口池不够时,更多线程只会更快失败。
- 追问:连接四元组是什么? 源 IP、源端口、目标 IP、目标端口。
- 追问:为什么长连接能缓解? 多个请求复用同一连接,减少临时端口分配和 TIME_WAIT。
- 追问:NAT 为什么容易中招? 多客户端共享出口 IP,端口映射资源集中消耗。
八、加强记忆
端口耗尽不是“服务器 80 端口没了”,而是客户端临时端口池被短连接和 TIME_WAIT 吃光。先看四元组,再看临时端口范围、TIME_WAIT、连接复用和 NAT 出口,排查路线就清楚了。