502 Bad Gateway 的意思是网关或代理从上游拿到的响应无效,或者连接在中途断了。在阿里云上,返回 502 的可能是负载均衡 SLB、CDN、WAF,也可能是你在 ECS 上自己装的 Nginx。和 504 不一样:504 是上游没在时限内回复,502 是上游回了东西但不对,或者连接断了。先弄清楚是哪一层返回的,后面的排查才不会走偏。

先看 502 是哪一层返回的
不同层的 502,线索差别很大。
- SLB 返回的 502:后端 ECS 没有响应,连接被重置,或者健康检查已经把后端判成异常。
- CDN 返回的 502:回源失败,通常是源站域名或 IP 不通,也可能是源站回了不合法的响应。
- Nginx 返回的 502:上游进程挂了,连接被拒绝,或者后端响应头超过了 proxy_buffer_size。
最快的办法是登录 ECS,翻一下 Nginx 的 error.log。拿报错时间去对,如果一条记录都没有,说明请求根本没到这台机器,问题大概率在前面的 SLB 或 CDN。
常见原因
长连接超时时间对不上
SLB 和后端之间会复用长连接。SLB 的空闲超时默认约 15 秒,可以在控制台改。如果后端 Nginx 的 keepalive_timeout 比它还短,Nginx 先把连接关了,SLB 却还往这条连接上塞新请求,结果就是 502。这种问题在流量低、连接大量空闲的时候最容易出现,高峰期反而不明显。
后端进程被占满
PHP-FPM 的 pm.max_children 设得太小,或者 Java 服务的线程池被打满,新请求就进不来。error.log 里常见的是 connect() failed (111: Connection refused) 或者 no live upstreams。
后端响应头太大
后端返回的 Cookie 或自定义头很长,超过 proxy_buffer_size 时,Nginx 会直接给出 502,日志里会有 upstream sent too big header。调大缓冲区能暂时解决,但更应该查的是后端为什么写了这么大的头,很多时候是 Cookie 里塞了不该塞的数据。
安全组或监听配置有误
安全组没放行后端端口,或者服务只监听了 127.0.0.1,SLB 连不上。这类问题多出现在迁移服务器或改安全组之后,改完就报错,回滚一下就能确认。
两个实际的例子
大促零点的间歇性 502
某电商站点在两台 ECS 上跑,前面挂着阿里云负载均衡。大促零点流量翻了一倍,502 比例约 3%,持续了大概 10 分钟。排查时发现 PHP-FPM 的 pm.max_children 只设了 20,高峰时进程全被占满,error.log 里全是 connect() failed。团队先调高进程数,并临时加了一台 ECS,502 降到 0.1% 以下。事后他们按单进程内存和机器总内存重新算了 max_children,又配了弹性伸缩,避免下次再靠手动扩容。
深夜才出现的周期性 502
某企业的 API 服务每隔几分钟会冒出少量 502,集中在深夜。查下来,SLB 的空闲超时设成了 60 秒,Nginx 的 keepalive_timeout 却只有 30 秒。深夜连接大量空闲,Nginx 在 30 秒时把连接关了,SLB 还在复用,请求就失败了。把 keepalive_timeout 调到 75 秒,高于 SLB 的空闲超时之后,问题就没再出现。
排查顺序
- 先确定报错的时间段、涉及的域名和接口,看是偶发还是持续。
- 去 SLB 控制台看监控和健康检查状态,确认后端有没有被摘除。
- 到 ECS 上看 Nginx 的 error.log,按报错时间找到具体的 upstream 错误。
- 检查后端的进程数、线程池,以及 CPU 和内存占用,判断是不是资源耗尽。
- 核对 SLB 空闲超时、Nginx keepalive_timeout 和安全组配置是否匹配。
预防
- 后端的 keepalive_timeout 一定要大于 SLB 的空闲超时。每次改完配置,最好回归测试一遍。
- 进程数上限按内存和单进程占用来算,别沿用默认值。
- 给 SLB 配健康检查和告警,502 比例一超阈值就能收到通知。
- 把 Nginx 的 error.log 接入日志服务,出问题时能按时间快速检索,省下逐台登录翻文件的时间。