SNAT 端口复用是什么
NAT 网关做源地址转换(SNAT)时,把 VPC 内大量私网地址折叠成少数几个公网 EIP。为了区分不同会话,转换后必须用「源 IP + 源端口」来标识:同一个 EIP 对同一个目的 IP 与端口,可用源端口数量只有几万个(受系统保留端口影响)。所以出口的容量有两个维度——带宽和会话数,带宽够不等于连接建得起来,高并发场景先被打满的往往是端口。
基本信息
| 会话标识 | 源 IP、源端口、目的 IP、目的端口、协议五元组 |
|---|---|
| 复用上限 | 单个 EIP 对同一目的 IP+端口可用源端口数量有限(几万量级) |
| 扩展方式 | 给 NAT 网关绑定多个 EIP 组成地址池,哈希分散源地址 |
| 会话释放 | 空闲超时到期回收,超时太长会拖住端口 |
| 典型症状 | 高峰期新建连接失败率上升,存量连接仍正常 |
| 实例侧视图 | Linux 上表现为 conntrack 表项增长,满表会丢包 |
典型使用场景
- 爬虫、采集类业务:对少量目标域名发起大量短连接,端口消耗极快
- 对外调用第三方 API 的服务,大量实例共享一个出口地址
- 消息推送/长连接网关:连接长期占用,会话数随在线终端线性增长
- 压测环境:验证出口在峰值连接数下是否仍能建连
- 排查「带宽有余量但连不上」的诡异故障,定位是否端口耗尽
症状与处置
| 症状 | 可能原因 | 处置方向 |
|---|---|---|
| 新建连接间歇失败,已有连接正常 | 目标集中导致端口复用受限 | 增加 SNAT EIP、分散目的地址 |
| 带宽曲线不高但业务报连接错误 | 会话数到达上限 | 看 NAT 连接数指标而非只看带宽 |
| 内网主机 conntrack 满 | 本机 NAT/转发表项溢出 | 调整 nf_conntrack_max 并缩短超时 |
| 失败集中在某时段 | 定时任务集中发起建连 | 错峰执行、加连接退避重试 |
| 切换 EIP 后短时好转又复发 | 只治了表象,源端口仍在被占满 | 按目的地址维度统计会话分布 |
观测与排查
观测与排查
sysctl net.netfilter.nf_conntrack_count # 当前表项数量
sysctl net.netfilter.nf_conntrack_max # 上限,接近上限会丢包
ss -s # 本机各状态 socket 统计
for i in $(seq 1 50); do \
curl -sS -m 5 -o /dev/null -w '%{http_code}\n' https://example.com/ || echo fail; done
# 统计失败次数:sudden spike 说明建连受限而非对端故障
dmesg | grep -i conntrack # 是否出现 table full dropping评估出口容量时把「目的地址集中度」一起算:连接分散在一千个目的地址上时,端口压力远小于全部打向同一个地址;反过来,采集类业务对同一站点的连接数上限可能远低于理论端口数。
缩短空闲超时能加快端口回收,但会影响长连接业务的稳定性(连接被提前清理)。调整前先确认业务侧有重连逻辑,并在测试环境验证。