高并发下nginx偶发502的根源是后端tcp连接队列满、文件描述符耗尽或内核参数限制;需调大net.core.somaxconn至4096以上,提升fs.file-max及进程级nofile限制,优化time_wait回收(tcp_fin_timeout、tcp_tw_reuse、tcp_timestamps),扩大ip_local_port_range,并检查nf_conntrack表容量。

高并发下 Nginx 偶发 502,往往不是 Nginx 本身扛不住,而是后端服务的 TCP 连接队列被撑满、文件描述符耗尽或内核网络参数限制导致连接建立失败——Nginx 尝试连后端时卡在 SYN_SENT 或收不到 ACK,最终超时返回 502。这类问题在流量高峰突增时特别典型,且日志里常出现 upstream timed out 或 connection refused,但后端进程明明活着。
下面重点讲怎么调系统内核参数,直击根源:
调整 accept 队列大小(关键!)
后端服务(如 Tomcat、Spring Boot、PHP-FPM)完成三次握手后,新连接会先进入内核的 accept queue(也叫 listen queue),等待应用调用 accept() 拿走。若队列满了,新连接会被丢弃,客户端看到的是连接超时,Nginx 则记为 connect failed → 502。
- 查当前值:
sysctl net.core.somaxconn
- 默认通常只有 128,远不够高并发场景。建议调到 4096 或更高:
echo 'net.core.somaxconn = 4096' >> /etc/sysctl.conf sysctl -p
- 同时确认后端服务自身的
backlog配置(如 Spring Boot 的server.tomcat.accept-count)不能小于这个值,否则取两者最小值。
增大文件描述符限制
每个 TCP 连接、每个打开的文件都占用一个 fd。Nginx worker 和后端服务同时大量建连时,容易触达系统级或进程级上限。
- 查系统全局上限:
cat /proc/sys/fs/file-max
- 若低于 100 万,建议调高:
echo 'fs.file-max = 2097152' >> /etc/sysctl.conf sysctl -p
- 再检查 Nginx 和后端服务的进程级限制(如
/etc/security/limits.conf):nginx soft nofile 65536 nginx hard nofile 65536 www-data soft nofile 65536 www-data hard nofile 65536
(根据实际运行用户调整)
优化 TIME_WAIT 连接回收(防端口耗尽)
高并发短连接场景下,大量连接关闭后进入 TIME_WAIT 状态,占着本地端口和内存。若 net.ipv4.ip_local_port_range 范围小、net.ipv4.tcp_fin_timeout 太长,可能导致“无端口可用”,Nginx 连不上后端。
- 缩短回收时间(谨慎使用,仅限内网可信环境):
echo 'net.ipv4.tcp_fin_timeout = 30' >> /etc/sysctl.conf echo 'net.ipv4.tcp_tw_reuse = 1' >> /etc/sysctl.conf # 允许将 TIME_WAIT socket 用于新连接(需 timestamps 开启) echo 'net.ipv4.tcp_timestamps = 1' >> /etc/sysctl.conf sysctl -p
- 扩大本地端口范围(默认 32768–60999,共约 28K):
echo 'net.ipv4.ip_local_port_range = 1024 65535' >> /etc/sysctl.conf
补充:别漏掉连接跟踪表(nf_conntrack)
如果用了 iptables/nftables 且开启连接跟踪(如做了 DNAT、或有复杂防火墙规则),nf_conntrack 表可能打满,导致新建连接被丢弃。
- 查使用情况:
cat /proc/sys/net/nf_conntrack_max cat /proc/sys/net/netfilter/nf_conntrack_count
- 若接近上限,适当调大(注意内存开销):
echo 'net.netfilter.nf_conntrack_max = 131072' >> /etc/sysctl.conf sysctl -p
这些参数改完后,必须重启后端服务(如 Java 应用、PHP-FPM),因为它们是在进程启动时读取内核参数的;Nginx reload 即可,无需重启。
不复杂但容易忽略











