属于大家的
VPS知识分享站

网站 502 错误怎么排查?Nginx、PHP-FPM 与后端超时的完整顺序(含 504)

先说结论:502 和 504 都不是“网站坏了”,而是网关(Nginx、CDN 或负载均衡)和后端之间出了问题。502 多半是后端没接上、进程崩了或返回了无效响应;504 是接上了但等太久。先分清这两个,再按“CDN → Nginx → 应用 → 数据库”的顺序查,比一上来重启服务器有效得多。

如果你现在正盯着报错页面,先做三件事:

  • 看错误日志:Nginx 的 error.log 会直接告诉你 upstream 是 refused、timed out 还是 invalid response
  • 看后端进程:PHP-FPM、Node、Java 进程还在不在,端口有没有在听
  • 看影响面:全站、单个站点还是某个接口,决定了你是先摘流量还是先修进程

下面按“分清错误 → 定位层级 → 常见原因 → 应急顺序 → 预防”讲,命令以 Nginx + PHP-FPM 为主,Node 和 Java 的检查点单独列。

30 秒分清 502、504 和 524

错误 含义 先查什么
502 Bad Gateway(Nginx/网关) 上游连接失败、进程崩溃,或返回了无法解析的响应 后端进程、socket/端口、应用日志
504 Gateway Timeout(Nginx/网关) 连上了上游,但在设定时间内没等到响应 应用慢查询、外部 API、超时配置
524(Cloudflare) Cloudflare 等源站响应超时(通常 100 秒) 源站处理时间、回源链路

三个错误经常混着出现:后端进程被打满时,一部分请求连接被拒(502),一部分排队超时(504)。所以不要只盯着一个错误码,先看时间分布和影响范围。

CDN、反向代理、应用服务器和数据库四层结构的等距示意图
502 和 504 只是网关层的症状,真正的故障点可能在下面任何一层。

先看三个地方

第一,Nginx 错误日志。 大多数答案就在这里:

tail -n 100 /var/log/nginx/error.log
# 常见关键字:
# connect() failed (111: Connection refused)
# upstream timed out (110: Connection timed out)
# upstream sent invalid response
# recv() failed (104: Connection reset by peer)

第二,后端进程和端口。

systemctl status php8.3-fpm --no-pager
ss -lntp | grep -E '9000|8080|3000'
ps aux | grep -E 'php-fpm|node|java' | grep -v grep

第三,应用自己的日志。 PHP 看 php-fpm 的 slow log 和应用的 error log;Node 看进程管理器的日志;Java 看 catalina.out 或应用日志。Nginx 只能告诉你“上游不对”,具体原因在后端。

502 的五个常见原因

  1. PHP-FPM 没启动或刚刚崩了:systemctl 显示 failed,或者进程在但 worker 全退出。先看 FPM 日志,不要直接重启了事。
  2. socket 路径或端口对不上:Nginx 配的是 unix:/run/php/php8.3-fpm.sock,FPM 实际监听的是别的路径;或者一边用 127.0.0.1:9000,另一边没开 TCP。改完配置记得 nginx -t 再 reload。
  3. pm.max_children 打满:并发一高,FPM 没有空闲 worker,新连接被拒。表现是 502 和 504 混合,FPM status 里 active processes 接近 max children。
  4. 应用进程崩溃:代码致命错误、扩展不兼容、内存超限被 OOM Killer 杀掉。dmesg 里能看到 oom-kill 记录。
  5. 权限或 SELinux 拦截:Nginx 用户读不到 socket、目录权限不对,或者 SELinux 不允许网络连接。日志里通常是 permission denied。

504 的五个常见原因

  1. 应用执行时间超过网关超时:Nginx 的 fastcgi_read_timeout 或 proxy_read_timeout 到了,应用还在跑。
  2. 数据库慢查询:一条没索引的 SQL 把连接池占满,后面所有请求排队。看慢查询日志和 SHOW PROCESSLIST。
  3. 外部 API 或第三方服务慢:支付、短信、对象存储、AI 接口,任何一个卡住都会把请求拖死。给外部调用单独设短超时和降级。
  4. 大文件、备份、导出任务:同步生成大文件、全量导出、备份压缩,都会长时间占用 worker。
  5. FPM 排队而不是执行慢:worker 被占满后,请求在 listen backlog 里排队,Nginx 看到的就是超时。这种情况加 timeout 没用,要加容量或限流。
两条数据路径,左边断裂冒火花,右边流入一个巨大的时钟
左边是 502:连接断了;右边是 504:连接还在,但时间耗尽了。

PHP-FPM 专项检查

先打开 FPM status,看看是“没 worker”还是“worker 都在忙”:

; pool 配置
pm.status_path = /fpm-status
pm.max_children = 20
pm.max_requests = 500
request_terminate_timeout = 60s
slowlog = /var/log/php-fpm/slow.log
request_slowlog_timeout = 5s
curl http://127.0.0.1/fpm-status?full

重点看三个数:active processes、listen queue、max children reached。active 长期贴着 max_children,说明容量不够;listen queue 不为 0,说明已经有排队;max children reached 大于 0,说明曾经打满。

调 pm.max_children 之前先算内存:每个 PHP worker 实际占多少 RSS,乘以 max_children,不能超过机器可用内存。盲目调到 100,只会把机器打到 OOM。

如果 slow log 里反复出现同一个脚本,先修代码或 SQL,不要只加 worker。加 worker 是把问题推迟,不是解决。

Node 和 Java 后端查什么

Node.js:先确认进程还在、端口在听,再看事件循环有没有被阻塞。单线程应用里,一个同步大计算或同步文件操作就能让所有请求排队。看进程管理器的重启次数、内存曲线和 event loop lag;必要时抓一次 CPU profile。

Java:看线程池是否打满、GC 是否频繁、数据库连接池是否耗尽。常用命令:

jstack <pid> > /tmp/threads.txt
jstat -gcutil <pid> 1000 10
ss -lntp | grep 8080

线程栈里大量线程卡在 socketRead 或数据库连接上,说明下游慢;大量线程在 GC 或锁上,说明是应用自身的问题。不要一看到 504 就调大 Tomcat 的 connectionTimeout。

10 分钟应急顺序

  1. 确认影响面:全站还是单站,静态资源是否正常,数据库是否可连。先判断是网关、应用还是数据库。
  2. 摘流量或降级:能切静态维护页就先切;不能切就限流、关闭非核心接口、把同步任务改成异步。
  3. 重启单个组件:只重启出问题的 FPM pool 或应用进程,不要直接 reboot 整台机器,重启会丢掉现场。
  4. 扩容或回滚:最近有发布就先回滚;容量不够就加 worker 或加机器,注意数据库连接数上限。
  5. 保留现场:重启前把 error.log、FPM status、慢查询、dmesg 复制出来,事后复盘用。

顺序很重要:先止损,再定位,最后才是优化。很多团队反过来,先花一小时研究日志,用户已经跑光了。

怎么避免下次

  • 监控 5xx 和 upstream 时间:不只看站点是否 200,要看 5xx 比例、upstream_response_time 的 p95、FPM active/max 比例。
  • 超时分层:CDN 100 秒、Nginx 60 秒、FPM 55 秒、数据库 5 秒、外部 API 3 秒。外层永远比内层长,内层先失败,外层才有机会返回明确错误。
  • 把慢任务挪走:导出、备份、图片处理、AI 调用走队列,不要占 Web worker。
  • 按站点拆 pool:一个站点被打满,不要带着整台机器一起挂。
  • 定期压测:知道自己的 QPS 拐点在哪,比出事时拍脑袋扩容靠谱。
带抽象曲线和仪表盘的监控面板与终端窗口
把 5xx 比例、upstream 时间和 FPM 并发放进监控,才能在下一次之前发现拐点。

常见问题 FAQ

Q1:502 一定是服务器坏了吗?

不一定。配置错误、socket 路径不对、应用崩溃、权限问题都会报 502。先看 Nginx error.log 的具体原因,再决定动不动服务器。

Q2:重启 PHP-FPM 有用吗?

能暂时恢复,但很可能复发。重启后要看 FPM 日志、slow log 和内存曲线,找到是容量、代码还是下游的问题。

Q3:504 把 timeout 调大就行吗?

不行。调大只是让用户等更久,根因可能是慢查询或外部 API。正确做法是给内层设更短的超时、做降级,同时修慢的地方。

Q4:Cloudflare 报 524,但源站看起来正常?

524 是 Cloudflare 等源站超时。用 curl 直接打源站 IP 并带 Host 头,测同一路径的耗时;如果源站确实超过 100 秒,先优化源站,而不是关 Cloudflare。

Q5:宝塔面板上怎么查?

面板里能看 Nginx 错误日志、PHP-FPM 状态和负载,但根因还是要回到日志和进程。面板的“重启”按钮只能当止损,不能当诊断。

Q6:502 和 504 会同时出现吗?

会,而且很常见。容量打满时,一部分连接被拒是 502,一部分排队超时是 504。看比例比看单个错误更有意义。

参考来源

总结

502 先查“有没有接上”,504 先查“为什么这么慢”。日志、进程、端口是三件最先看的东西;止损、定位、优化是三步不能颠倒的顺序。把超时分层和监控做好,下次再出问题,你至少能在十分钟内知道该动哪里。

如果排查下来是机器本身的容量或线路问题,可以换一台干净的环境做对照测试。萤光云香港 CN2 VPS 适合做华南及亚太业务的接入和压测,按小时开一台,先把 Nginx 和 FPM 的配置跑通再迁正式流量。

相关推荐

赞(0)
未经允许不得转载:VPS知识分享站 » 网站 502 错误怎么排查?Nginx、PHP-FPM 与后端超时的完整顺序(含 504)