nginx作为tcp网关因端口耗尽触发502错误,需启用tcp_tw_reuse、扩大本地端口范围,并在upstream中配置keepalive连接池以复用连接。

核心问题在于:Nginx作为TCP网关大量发起上游连接时,若Linux内核未启用端口重用(tcp_tw_reuse),会导致本地端口快速耗尽,触发 Cannot assign requested address 错误,进而引发502 Bad Gateway。
确认是否因端口耗尽导致报错
先验证现象是否匹配:
- 执行
ss -s | grep "TCP:",重点关注TIME-WAIT数量。若远高于 28k(默认端口范围 32768–61000 共 28232 个),且持续增长,基本可判定为端口不足 - 检查 Nginx error log,出现大量
connect() failed (99: Cannot assign requested address)或upstream prematurely closed connection - 观察
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}',若TIME-WAIT占比极高(如超 80%),而ESTABLISHED很低,说明连接复用失败、全靠新建
开启内核级TCP端口重用
在服务端(即运行 Nginx 的机器)执行以下操作:
- 临时生效(重启失效):
sysctl -w net.ipv4.tcp_tw_reuse=1sysctl -w net.ipv4.ip_local_port_range="1024 65535" - 永久生效:向
/etc/sysctl.conf追加两行net.ipv4.tcp_tw_reuse = 1net.ipv4.ip_local_port_range = 1024 65535
然后执行sysctl -p -
注意:
tcp_tw_reuse仅对客户端角色的连接生效(即 Nginx 主动连 upstream 时),且要求时间戳选项(net.ipv4.tcp_timestamps=1)已开启——现代内核默认开启,无需额外设置
配套优化Nginx stream模块连接行为
光开内核参数不够,必须让 Nginx 少建新连接:
- 在
upstream块中启用连接池:keepalive 32;(建议设为后端单机处理能力的 1/2~1/3)keepalive_timeout 60s;(避免空闲连接僵死) - 禁用缓冲防止粘包延迟:
proxy_buffering off;(stream 模块默认关闭,但显式声明更稳妥) - 确保 upstream server 地址使用 IP 而非域名,避免 DNS 查询引入额外延迟和连接中断风险
验证复用是否真正生效
调优后需观测指标确认效果:
- 用
nginx -s reload生效配置后,压测期间持续监控:ss -tan state time-wait | wc -l应明显下降(理想值稳定在数百以内) - 通过
nginx-vts-exporter查看stream_upstream_connections_idle是否持续有值,且stream_upstream_connections_active波动平缓 - 对比后端服务器上的
ss -tn state established | wc -l,应显著低于客户端并发数——说明连接被复用了











