502 表示 Nginx 无法连接上游(如服务未启动、端口错误、上游主动断连),504 表示 Nginx 连接上游成功但响应超时;需通过 error.log 中的 connect() failed、upstream timed out 等关键词及 upstream 字段精准定位,并结合上游日志与 curl 模拟验证。

502 和 504 都是 Nginx 返回的网关类错误,但它们指向完全不同的故障环节。快速区分并精准定位,关键不在猜,而在日志里那几行带时间戳和错误码的输出。
看 error.log 第一眼:先分清是“连不上”还是“等不到”
Nginx 的 error.log 是唯一可信的起点。打开后直接搜索关键词,不翻全文:
-
出现 connect() failed (111: Connection refused) → 502,上游根本没监听端口。常见于服务未启动、端口写错(比如配了
8000,实际只监听8001)、Docker 容器未就绪。 -
出现 upstream timed out (110: Connection timed out) → 大概率是 504,Nginx 连上了,但上游响应太慢或卡死。重点查
proxy_read_timeout和上游处理逻辑。 - 出现 upstream prematurely closed connection → 502,上游主动断开,可能是进程崩溃、OOM 被杀、或 FastCGI/HTTP 协议头异常(如多空行、非法字符)。
结合 upstream 字段缩小范围
每条错误日志末尾通常带 upstream: "http://127.0.0.1:8000/xxx" 或 upstream: "unix:/var/run/php-fpm.sock"。这个字段告诉你 Nginx 实际发往哪里:
- 如果是
http://地址,立刻在本机用curl -v http://127.0.0.1:8000/health直连测试,看是否真能通、响应是否合法(HTTP 状态码 200 + 正确 header)。 - 如果是
unix:socket,检查路径是否存在、权限是否为 Nginx worker 进程可读写(ls -l /var/run/php-fpm.sock),再查对应服务(如 php-fpm)是否运行中(systemctl status php-fpm)。
对比时间戳,关联上下游日志
记下 error.log 中某条 502 错误的时间(如 2026/10/01 06:42:17),然后做两件事:
- 去上游服务自己的日志里(如
/var/log/myapp/app.log或journalctl -u myservice -S "2026-10-01 06:42:15" -U "2026-10-01 06:42:20"),找同一秒附近是否有 panic、segfault、connection reset、OOM killer 记录。 - 如果上游是 Java/Tomcat,重点看 GC 日志或线程 dump;如果是 Python/Gunicorn,看是否有 worker timeout 或 signal 15/9;如果是 Node.js,查是否有 event loop blocked 或 unhandledRejection。
用 curl 模拟 Nginx 请求行为
别只用浏览器刷,要用和 Nginx 一致的方式复现:
- 加上 Host 头:
curl -H "Host: api.example.com" http://127.0.0.1:8000/xxx,模拟 Nginx 的proxy_set_header Host $host;行为。 - 加超时限制:
curl --connect-timeout 5 --max-time 30 http://127.0.0.1:8000/xxx,验证是否真超时。 - 抓原始响应:
curl -v http://127.0.0.1:8000/xxx 2>&1 | head -n 50,确认返回的是否是标准 HTTP 响应(有 Status-Line、Server、Content-Type 等 header)。


















