Nginx 返回 502 时,按连接、协议和响应头定位问题

09-30 10阅读

网页出现 502 时,先记录时间、访问路径和触发条件,再去对应的 Nginx 实例找日志。站点前面如果还有 CDN 或负载均衡,也要确认故障来自哪一层。本文针对 proxy_pass 转发 HTTP 服务的场景;PHP-FPM 的 FastCGI 配置需要单独检查。下面的地址、端口和路径均为示例,只对自己有权管理的服务操作。

先确认检查的是当前实例

sudo nginx -t
sudo tail -n 100 /var/log/nginx/error.log

日志位置以实际 error_log 配置为准。自定义配置路径或多实例部署应使用对应的启动参数,容器部署则检查容器内配置和日志。nginx -t 检查语法及引用文件,不能证明后端业务健康。需要查看展开配置时可在本机运行 nginx -T,但不要直接公开完整输出,其中可能包含内部地址或凭据。

从代理所在环境访问同一个上游

先确认匹配请求的 location、proxy_pass 协议、端口、转发路径和 Host。假设应用实际监听 HTTP 8080,且已有无副作用的健康检查接口,可进行一次有限时长的请求:

curl --connect-timeout 3 --max-time 10 -i \
  -H 'Host: app.example.com' \
  http://127.0.0.1:8080/health

Host 应替换成代理真正发送的值;未显式配置时不要假定它等于浏览器域名。若 Nginx 在容器中,127.0.0.1 通常指向这个容器自身,宿主机上请求成功也不能证明容器能访问上游。应在相同网络环境中测试实际服务名和端口。HTTP 404 表明收到了 HTTP 响应,但仍需核对路径;健康检查成功也不能替代故障接口的验证。

根据日志缩小范围

Nginx 返回 502 时,按连接、协议和响应头定位问题

图:从 Nginx 日志中的线索出发,分别检查上游连接、协议与响应头;插图为概念示意。

  • Connection refused:优先核对上游进程是否运行、监听地址和端口是否正确,并检查网络侧是否主动拒绝连接

  • upstream prematurely closed connection:检查同一时刻的应用日志、进程退出或重启记录,以及 HTTP/HTTPS 协议是否匹配

  • upstream sent too big header:查看响应头,尤其是异常膨胀的 Cookie;确认合理大小后再评估缓冲配置,不要按响应正文大小猜测

  • upstream timed out:继续区分发生在连接还是读取阶段,结合实际状态码判断;超时也常表现为 504,不能把所有网关错误归为一种原因

一次只改一个有证据的问题

改配置前留存可回退版本。读取超时 proxy_read_timeout 限制的是相邻两次读取之间的等待,并非整个响应的总时长;调大它不能解决端口错误或进程崩溃。只有确需修改时,才在测试通过后重载对应实例:

sudo nginx -t && sudo nginx -s reload

随后从真实入口复测原请求,并同时核对应用日志与 Nginx 日志。若已有 $upstream_addr、$upstream_status 和耗时字段,可用它们定位实际命中的后端。记录修改项与前后现象,保留回退方式,直到原故障路径稳定恢复。

官方参考

文章版权声明:除非注明,否则均为云鹊BLOG原创文章,转载或复制请以超链接形式并注明出处。