Nginx 502 Bad Gateway常见原因和解决办法
前言
网站突然打不开了,浏览器显示"502 Bad Gateway"?这是Nginx最常见的报错之一。本文讲502是什么意思、常见原因、怎么排查和解决。
一、502是什么意思
502 Bad Gateway = Nginx作为代理,从后端服务器(比如PHP-FPM)拿不到正常的响应。
简单说:Nginx收到了你的请求,然后去问后端"给我数据",后端没理它或者报错了,Nginx就返回502。
二、常见原因
原因1:PHP-FPM没启动
后端PHP服务没跑,Nginx找不到人。
检查:
ps aux | grep php-fpm
没输出就是没启动。
启动:
systemctl start php-fpm
或者:
service php-fpm start
原因2:PHP-FPM端口不对
Nginx配置里写的PHP-FPM地址不对。
比如:
fastcgi_pass 127.0.0.1:9000;
但PHP-FPM实际监听的是 /tmp/php-cgi.sock。
检查PHP-FPM监听:
netstat -tlnp | grep php-fpm
或者:
ss -tlnp | grep php-fpm
原因3:PHP代码报错
PHP代码有致命错误,直接挂了。
看PHP错误日志:
tail -f /var/log/php-fpm/www-error.log
或者:
tail -f /var/log/php/error.log
原因4:PHP超时了
程序跑太慢,超过Nginx或PHP-FPM的超时时间。
改Nginx超时:
fastcgi_read_timeout 300;
改PHP-FPM超时:
request_terminate_timeout = 300
原因5:PHP-FPM进程数不够
请求太多,PHP-FPM忙不过来。
看进程数:
ps aux | grep php-fpm | wc -l
改配置:
pm.max_children = 50
pm.start_servers = 20
原因6:内存不够了
PHP进程占满内存,系统把PHP杀了。
看内存:
free -h
看dmesg:
dmesg | grep oom
三、排查步骤
第一步:看Nginx错误日志
tail -f /var/log/nginx/error.log
常见报错:
| 报错 | 含义 |
|---|---|
| connect() failed (111: Connection refused) | PHP-FPM没启动 |
| Primary script unknown | 文件路径不对 |
| upstream timed out | PHP超时了 |
| recv() failed (104: Connection reset by peer) | PHP-FPM挂了 |
第二步:看PHP-FPM状态
systemctl status php-fpm
看是不是running。
第三步:看PHP错误日志
tail -f /var/log/php-fpm/www-error.log
看PHP代码有没有报错。
第四步:看系统资源
top
free -h
df -h
看CPU、内存、磁盘够不够。
四、常见解决方法
方法1:重启PHP-FPM
systemctl restart php-fpm
方法2:改Nginx配置
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
# 超时时间
fastcgi_read_timeout 300;
fastcgi_send_timeout 300;
}
方法3:改PHP-FPM进程数
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 30
改完重启:
systemctl restart php-fpm
方法4:开PHP错误显示
display_errors = On
error_reporting = E_ALL
五、常见坑
坑1:只重启Nginx,不重启PHP-FPM
502是后端的问题,重启Nginx没用。
正确: 重启PHP-FPM。
坑2:文件路径不对
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
错! 应该是:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
坑3:PHP-FPM版本不对
装了PHP7但Nginx还找PHP5的sock。
检查:
ls -la /var/run/php/
坑4:权限问题
PHP-FPM没权限读网站目录的文件。
解决:
chown -R www:www /www/wwwroot/
总结
记住:
- 502 = Nginx拿不到后端响应
- 先看Nginx错误日志
- 再看PHP-F启没启动
- 然后看PHP代码有没有报错
- 最后看系统资源够不够
最快排查:
tail -f /var/log/nginx/error.log
systemctl status php-fpm
遇到问题加QQ23979811 协助处理
Nginx报502 Bad Gateway完整排查思路(PHP-FPM场景)
前言
502 Bad Gateway 是 Nginx 最常见的报错之一,尤其是 LNMP 架构下,Nginx 把 PHP 请求转发给 PHP-FPM,PHP-FPM 出问题了 Nginx 就报 502。本文讲一下完整的排查思路。
502 是什么意思
502 表示 Nginx 作为反向代理,去请求后端服务(PHP-FPM)的时候,后端没响应或者报错了。
注意: 502 不是 Nginx 的问题,是后端 PHP-FPM 的问题。
排查步骤
第一步:检查 PHP-FPM 服务是否在运行
systemctl status php-fpm
如果显示 inactive (dead),说明 PHP-FPM 挂了,启动它:
systemctl start php-fpm
systemctl enable php-fpm
第二步:检查 Nginx 和 PHP-FPM 的通信配置
看 Nginx 配置里的 fastcgi_pass 对不对:
grep fastcgi_pass /etc/nginx/nginx.conf
常见的配置:
# 用 socket 文件
fastcgi_pass unix:/run/php-fpm/www.sock;
# 用 TCP 端口
fastcgi_pass 127.0.0.1:9000;
问题1:socket 文件路径不对
Nginx 配置里写的 socket 路径和 PHP-FPM 实际的不一致。
PHP-FPM 的 socket 路径在 /etc/php-fpm.d/www.conf 里:
grep listen /etc/php-fpm.d/www.conf
确保两边路径一致。
问题2:端口被占
如果用 9000 端口,检查一下是不是被别的进程占了:
lsof -i:9000
第三步:看错误日志
Nginx 错误日志:
tail -f /var/log/nginx/error.log
PHP-FPM 错误日志:
tail -f /var/log/php-fpm/error.log
PHP 慢日志:
tail -f /var/log/php-fpm/www-slow.log
根据日志里的报错信息找原因。
第四步:常见原因
原因1:PHP-FPM 进程数不够
访问量大的时候,PHP-FPM 进程都被占满了,新请求排队超时。
解决: 增加 PHP-FPM 进程数。
编辑 /etc/php-fpm.d/www.conf:
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 30
改完重启:
systemctl restart php-fpm
原因2:PHP 脚本执行超时
PHP 脚本执行时间太长,超过了 Nginx 的超时时间。
解决: 调大超时时间。
Nginx 配置里:
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
PHP 配置里:
max_execution_time = 300
原因3:PHP 内存不足
PHP-FPM 进程内存溢出,导致进程崩溃。
解决: 调大 PHP 内存限制:
memory_limit = 256M
或者减少 PHP-FPM 进程数,避免内存不够。
原因4:文件权限不对
Nginx 运行的用户和 PHP-FPM 运行的用户不一致,导致 PHP-FPM 读不到文件。
解决: 确保 Nginx 和 PHP-FPM 用同一个用户(一般是 www)。
PHP-FPM 配置 /etc/php-fpm.d/www.conf:
user = www
group = www
然后把网站文件的属主改成 www:
chown -R www:www /var/www/html
第五步:重启所有服务
改完配置后重启:
systemctl restart php-fpm
systemctl restart nginx
常见坑
坑1:只重启了 Nginx
改了 PHP 配置但只重启了 Nginx,PHP-FPM 还是老配置。
解决: PHP 配置改了要重启 PHP-FPM,Nginx 配置改了要重启 Nginx。
坑2:socket 文件权限不对
PHP-FPM 的 socket 文件权限是 600,Nginx 用户读不到。
解决: 改 socket 文件权限:
listen.mode = 0666
或者改 socket 文件的属主:
listen.owner = www
listen.group = www
坑3:PHP-FPM 挂了但没自动重启
PHP-FPM 进程崩溃了,没人自动拉起来。
解决: 配置 systemd 自动重启:
systemctl edit php-fpm
加:
[Service]
Restart=always
RestartSec=2
总结
502 排查步骤:
- 先看 PHP-FPM 是不是挂了 →
systemctl status php-fpm - 再看 Nginx 配置对不对 → fastcgi_pass 路径/端口
- 看错误日志 → Nginx error.log + PHP-FPM error.log
- 常见原因 → 进程数不够、超时太短、权限不对、内存不足
记住:502 问题出在后端,不是 Nginx 的锅。
遇到问题加QQ23979811 协助处理