作者小头像 Lv.1
16 成长值

个人介绍

这个人很懒,什么都没有留下

感兴趣或擅长的领域

暂无数据
个人勋章
TA还没获得勋章~
成长雷达
10
6
0
0
0

个人资料

个人介绍

这个人很懒,什么都没有留下

感兴趣或擅长的领域

暂无数据

达成规则

发布时间 2026/10/23 11:35:10 最后回复 yd_222513545 2026/10/23 15:24:41 版块 开发者空间
15 3 0
他的回复:
Nginx 偶发 502 Bad Gateway,后端服务健康检查正常、进程存活、没有大量宕机。502 本质:Nginx 尝试向后端建立连接 / 收发数据失败,不是后端进程挂了才会报 502;健康检查只是 “探针能不能通”,和真实业务请求链路不一样。一、先分清两个关键点(最容易踩坑)Nginx proxy_pass 转发 502:Nginx 和后端 TCP 层面通信失败(连不上、RST、超时被断开)后端健康检查正常:健康探针一般是轻量 GET / 端口探测,请求耗时短、负载低;业务请求更大、更慢、长连接多,场景完全不同常见一句话:健康检查只测 “能不能 ping 通 / 简单访问”,测不出高并发下的连接、队列、内核、文件句柄问题。二、优先抓日志(必做)1)打开 nginx error.log,看 502 对应的错误关键词配置里确保 error_log 级别 error 以上,最好临时调到 warn:error_log logs/error.log warn;高频报错关键字对应原因:connect() failed (111: Connection refused) → 端口没监听、后端临时关闭监听、端口被占、防火墙 / 安全组拦截瞬时连接connect() failed (110: Connection timed out) → 建连超时,网络链路、后端 accept 队列满recv() failed (104: Connection reset by peer) → 后端主动 RST 断开连接(后端内核、连接池、限流、OOM、GC 停顿、容器被掐连接)send() failed (32: Broken pipe) → 连接已经被后端关掉,Nginx 还在发数据✅ 一定要带上 $upstream_addr $upstream_status $upstream_response_time 记录访问日志,看是不是固定某一台后端实例偶发。log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" "$http_user_agent" ' '$upstream_addr $upstream_status $upstream_response_time';三、高发原因分类排查(按概率排序)1. 后端 listen 的 accept 队列满(非常符合:健康检查正常、业务偶发 502)后端服务(Java/Go/Python)listen backlog 太小,并发突增时,内核 TCP 半连接队列满,新连接直接丢弃。查看当前队列溢出:# Linuxss -s# 看 TCP 溢出计数器:TW、TIME_WAIT、SYN、embryonic overflownetstat -s | grep -i listen现象:短连接高并发场景最容易出现,健康探针请求量低,打不爆队列,所以健康检查一直 OK。 验证:调高 backlog + 内核参数 net.core.somaxconn2. Nginx 与后端之间的长连接池配置不匹配(upstream keepalive)很多人配置了 keepalive 复用连接,但是:后端空闲连接超时时间 Nginx keepalive 空闲超时后端主动把空闲连接关闭了,Nginx 连接池里还拿着这条 “死连接”,下一次复用的时候直接 502 /reset by peer 典型:Nginx keepalive 60s,后端服务连接空闲 30s 就关闭。 ✅ 方案:Nginx keepalive 超时小于后端空闲超时;或者开启 proxy_next_upstream 重试(注意幂等!)upstream backend { server 127.0.0.1:8080; keepalive 32; # 空闲连接数,不是最大并发}3. 网络层问题(容器 / 云环境高频)云主机安全组、iptables、firewalld 有连接跟踪满(nf_conntrack):并发连接打满 conntrack 表,新连接丢包,偶发不通cat /proc/sys/net/netfilter/nf_conntrack_countcat /proc/sys/net/netfilter/nf_conntrack_max容器网络:overlay 网络、service 转发、kube-proxy ipvs/iptables 模式下,连接漂移、端口回收问题中间有 SLB / 网关,不是直连后端:中间节点会话老化4. 后端资源瞬时抖动(进程活着,但内核拒绝新连接)后端进程虽然在,但是:文件句柄 ulimit -n 打满,无法 accept 新 socketlsof -p | wc -lCPU 100%、Full GC、线程池耗尽:进程不死、端口监听还在,但是没法 accept 新 TCP 连接健康探针请求极快,线程一腾出来就能响应;业务请求占满线程池,新 TCP 连接在内核队列卡住,返回 RST。5. proxy 参数超时配置不合理,和后端时序冲突proxy_connect_timeout 5s;proxy_send_timeout 60s;proxy_read_timeout 60s;不是越大越好:如果后端卡住不回包,Nginx 超时断开报 502; 区分:connect_timeout(建连)、read_timeout(已经连上,等待响应)。6. upstream 重试策略陷阱proxy_next_upstream error timeout invalid_header http_500 http_502; 开启后 Nginx 会自动切下一台重试;如果日志里看到频繁切换 upstream 节点,说明单点不稳定; ⚠️ POST / 非幂等接口不要随便开重试,会造成重复提交。四、快速定位工具包(现场抓)抓包:Nginx 机器 tcpdump 抓后端端口流量,502 发生时看是 SYN 没 ACK,还是收到 RSTtcpdump -i eth0 host 后端IP and port 8080监控埋点:Nginx:nginx-prometheus-exporter,监控 nginx_upstream_responses_total{status="502"}、upstream 连接数后端:TCP backlog 溢出、连接数、线程池、GC、fd、CPU压测复现:低并发正常,加压后稳定复现 502 → 基本锁定队列 / 句柄 / 连接池上限五、最简排查顺序(线上故障时直接照这个走)捞 Nginx error.log,拿到 502 对应的错误描述(最重要一步)核对 access log 的 $upstream_addr,确认是单点还是随机所有节点检查后端机器:somaxconn、backlog、nf_conntrack、ulimit fd核查 upstream keepalive 长连接空闲超时配置抓包确认是【建连失败】还是【连接建立后被 RST】对比健康检查的请求路径、请求方式、并发模型,和真实业务请求差异补充区分 502 vs 504很多人混淆:502 Bad Gateway:Nginx 和后端 TCP 通信失败(连不上、被 RST)504 Gateway Timeout:TCP 连接成功,但是后端迟迟不返回响应(proxy_read_timeout)