首页 > Technology > 正文

VPS 502 / 504 Bad Gateway 怎么办?完整排查清单与修复

fenij 2026-08-11 42 Technology

502 Bad Gateway、504 Gateway Timeout 这两个错一出来,整个站就废了,但 Nginx 日志又臭又长,找不到头绪。其实只要按一个固定套路查,10 分钟内基本能定位到具体服务。

502 和 504 是不一样的故障

别把它们当一回事:

🔌
502
连不上 / 进程挂了 / 提前断开
⏱️
504
后端太慢 / 超时断开

502 的本质是「Nginx 试图把请求转给上游,但上游没给一个有效响应」,常见:PHP-FPM 进程崩了、socket 路径配错、权限拒绝、OOM Killed。504 的本质是「上游在 proxy_read_timeout 内没干完活」,常见:慢 SQL、上游连接池打满、外部 API 慢、文件 IO 阻塞。

第一步:直连后端做二分

绕过 Nginx,直接 curl 后端端口,10 秒把问题切成两半:

grep -r 'proxy_pass\|upstream' /etc/nginx/conf.d/ | grep -v '#'

拿到后端地址(比如 127.0.0.1:9000 是 PHP-FPM、127.0.0.1:8080 是 Node),直接敲:

curl -I --connect-timeout 5 --max-time 10 http://127.0.0.1:8080

curl 直连结果 结论 下一步
返回 200 后端没问题 回头查 Nginx 配置
Connection refused 后端进程没起 systemctl status / 重启
超时 / 极慢 后端卡死 查资源 / 慢 SQL

第二步:盯 Nginx error.log 三个关键词

tail -200 /var/log/nginx/error.log

日志又臭又长,但只看三组关键词就够定性:

日志关键词 含义 下一步
Connection refused (111) 端口没人接 重启后端 / 改 fastcgi_pass
upstream timed out (110) 后端太慢 调大超时 / 优化 SQL
no live upstreams 后端全军覆没 扩容 / 看是不是配错
Permission denied (13) socket 权限 / SELinux chown / chmod / setsebool

注意日志里的 upstream: "http://10.0.1.10:8080/api/report" 这段——它精确告诉你哪个节点哪个接口在出问题,特别是排 504 时这是金子。

第三步:基本盘检查 30 秒

错误发生的那一刻同时跑:

date && uptime && free -h && df -h && df -i && ss -lntp | sed -n '1,12p'

重点:

  • 磁盘 / inode 100%:502/504 经常从这开始级联,先腾空间
  • swap 用满:物理内存已经吃光,慢下来导致 504
  • 端口是否真的在监听:ss -lntp 看有没有 9000 / 8080

第四步:常见修法清单

502 是「连不上」,重点查连接:

  • PHP-FPM 没启动:systemctl status php8.3-fpm 看状态
  • fastcgi_pass 路径错:nginx -T | grep fastcgi_pass 看实际生效值
  • socket 权限错:ls -l /run/php/php8.3-fpm.sock 看属主属组是不是 www-data
  • 进程被打爆 OOM:dmesg | grep -i oom 看内核日志

504 是「太慢」,重点查超时和队列:

  • 调大 Nginx 超时:proxy_connect_timeout 30s; proxy_read_timeout 90s; proxy_send_timeout 90s;
  • 调大 PHP-FPM 进程数:pm.max_children 视内存调,512MB 内存建议 8~12
  • 查慢 SQL:SET GLOBAL slow_query_log = 'ON';

不要靠重启掩盖根因

重启 Nginx、PHP-FPM、应用服务有时能恢复,但重启只是把现场清掉,下个高峰期同一原因还会炸。正确做法是这次顺便记下来根因:是不是 PHP-FPM worker 数不够?是不是某个接口慢?是不是磁盘快满了?写到 wiki 里,下次少走弯路。

常见问题

Q:502 经常在高峰期偶发,低谷又正常,怎么定位?
A:高峰期 PHP-FPM worker 打满会触发 502。压测前先把 pm.status_list = /run/php/php-fpm-status.sock 打开,ab 跑的时候用 curl http://127.0.0.1/status 看 active process 是否接近 max_children。

Q:用了 Docker,502 / 504 怎么查?
A:思路完全一样——docker exec -it web sh 进容器,按上面步骤查;或在宿主机用 docker logs web --tail 200 看应用日志。注意容器之间网络是不是通的,docker network inspect 看 IP 段。

Q:重启后马上又 502,是不是没救?
A:八成是「上游没启动完,Nginx 已经接到了请求」。Nginx 默认会把请求打到 upstream 列表第一项,启用了 proxy_next_upstream + proxy_next_upstream_tries 2 可以让第一个挂了自动试下一个。

按「直连后端 → 看 error.log → 检查基本盘 → 修具体环节」这套顺序,502/504 在 10 分钟内基本都能落点。如果还卡在中间,把 error.log 末尾几行 + upstream 配置贴到 fenij.com 留言,我帮你接着查。

排错自查清单

  • ☐ 502 和 504 是不一样的故障:别把它们当一回事:
  • ☐ 第一步:直连后端做二分:绕过 Nginx,直接 curl 后端端口,10 秒把问题切成两半:
  • ☐ 第二步:盯 Nginx error.log 三个关键词:tail -200 /var/log/nginx/error.log
  • ☐ 第三步:基本盘检查 30 秒:错误发生的那一刻同时跑:
  • ☐ 第四步:常见修法清单:502 是「连不上」,重点查连接:
  • ☐ 不要靠重启掩盖根因:重启 Nginx、PHP-FPM、应用服务有时能恢复,但重启只是把现场清掉,下个高峰期同一原因还会炸。正确做法
  • ☐ 常见问题:Q:502 经常在高峰期偶发,低谷又正常,怎么定位?A:高峰期 PHP-FPM worker 打满会触发 50

关键命令速查

  • proxy_read_timeout
  • grep -r 'proxy_pass\|upstream' /etc/nginx/conf.d/ | grep -v '#'
  • curl -I --connect-timeout 5 --max-time 10 http://127.0.0.1:8080
  • tail -200 /var/log/nginx/error.log
  • upstream: "http://10.0.1.10:8080/api/report"
  • date && uptime && free -h && df -h && df -i && ss -lntp | sed -n '1,12p'

相关延伸

更系统的排查思路,见 Technology 分类归档

相关完整手册

系统化的排查与配置思路,建议顺手收藏这几篇完整手册: