访问网站突然弹出「502 Bad Gateway」,说明 Nginx 自己还活着,但它把请求转给后端(PHP-FPM、Node、Tomcat、上游服务等)时,后端没给回有效的响应。也就是说,问题多半出在 Nginx 后面那一环。下面按出现频率从高到低,把定位和修复的步骤列出来,命令都能直接复制用。
第一步:看错误日志,确定 502 的具体原因
别凭感觉猜,先翻日志。Nginx 的错误日志会直接告诉你上游出了什么状况:
tail -50 /var/log/nginx/error.log
常见的三类关键字对应三种原因:
- connect() failed (111: Connection refused):后端服务没起来,或者监听的端口/套接字对不上;
- upstream timed out:后端太慢,超过了 Nginx 的等待时间;
- no live upstreams:upstream 里所有后端都被判为不可用。
后端服务挂了:最常见的原因
日志要是显示 Connection refused,先确认后端进程的状态。以最常见的 PHP-FPM 为例:
systemctl status php8.1-fpm
systemctl restart php8.1-fpm
再确认 Nginx 配置里 fastcgi_pass 指向的地址,跟 PHP-FPM 实际监听的地址一致:
grep -r "fastcgi_pass" /etc/nginx/
grep "listen" /etc/php/8.1/fpm/pool.d/www.conf
一边用 127.0.0.1:9000、一边用 unix socket,是新手部署时最典型的 502 成因。把两边改成一致,再执行 nginx -t && systemctl reload nginx 就好了。
后端超时:调大超时或优化慢请求
日志如果是 upstream timed out,说明后端在处理但太慢。临时缓解可以在 server 或 location 块里把超时调大:
proxy_connect_timeout 60s;
proxy_read_timeout 120s;
fastcgi_read_timeout 120s;
不过调超时只是止痛药,根子通常是慢 SQL、外部接口卡顿,或者 PHP-FPM 进程数不够。顺手查一下 PHP-FPM 是不是进程耗尽了:
grep "max_children" /var/log/php8.1-fpm.log
要是频繁出现 reached max_children,就适当调大 pm.max_children(注意留点内存余量:可用内存 ÷ 单进程平均占用)。
资源耗尽与其他系统层原因
- 内存不足:
free -h看一下,后端进程可能被 OOM Killer 干掉了,用dmesg | grep -i kill能确认; - 磁盘写满:
df -h检查,磁盘 100% 时 PHP 的会话、日志写不进去,同样会引发 502; - SELinux 拦截:CentOS 上若 Nginx 连不上上游端口,执行
setsebool -P httpd_can_network_connect 1; - 缓冲区过小:偶发 502 且日志提示 upstream sent too big header 时,调大
fastcgi_buffers 16 16k; fastcgi_buffer_size 32k;。
验证修复是否生效
每次改完配置都按这个顺序走一遍,免得把网站彻底搞挂:
nginx -t
systemctl reload nginx
curl -I http://127.0.0.1/
返回 200 就说明恢复正常了。建议再配个简单监控(比如 crontab 里每分钟 curl 探活并告警),下次 502 就能第一时间发现。
常见问题
502 和 504 有什么区别?
502 是后端返回了无效响应或干脆拒绝连接;504 是后端在超时时间内完全没响应。502 多查”服务挂没挂”,504 多查”为什么这么慢”。
重启 Nginx 能解决 502 吗?
多数情况下不能。502 的根子在后端的,该优先重启的是 PHP-FPM、Node 这些上游服务,而不是 Nginx。
偶尔出现一次 502 需要处理吗?
偶发的 502 通常是后端进程短暂繁忙或重载导致的,可以先观察频率;要是每天都出现好几次,就得按上面去查进程数、内存和慢请求了。
如果按上面几步还没解决,欢迎到 fenij.com 评论区留言,把你当时的报错日志贴出来,我们帮你一起分析。