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 协助处理
PHP开启错误显示,php.ini配置修改
前言
PHP报错了,页面白屏或者500,啥也不显示,不知道哪错了?开了错误显示就能看到具体错误了。本文讲怎么改php.ini开启错误显示。
一、为什么不显示错误
生产环境为了安全,默认不显示错误,防止暴露敏感信息(路径、数据库密码等)。
但开发的时候就不方便了,啥也看不到。
二、找到php.ini
找php.ini位置
php --ini
输出:
Loaded Configuration File: /etc/php.ini
或者:
/etc/php/7.4/cli/php.ini
注意:CLI和FPM的php.ini可能不一样。
看当前加载的是哪个
写个phpinfo:
<?php
phpinfo();
?>
浏览器访问,看Loaded Configuration File。
三、修改php.ini
1. 显示错误
display_errors = On
2. 报错级别
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
或者全开:
error_reporting = E_ALL
3. 错误日志
log_errors = On
error_log = /var/log/php_errors.log
4. 显示启动错误
display_startup_errors = On
四、改完重启
PHP-FPM
systemctl restart php-fpm
或者:
systemctl reload php-fpm
Apache
systemctl restart httpd
五、代码里临时开启
不想改php.ini,在代码开头加:
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
或者:
ini_set('error_reporting', E_ALL);
ini_set('display_errors', 1);
六、常见错误类型
E_ALL
所有错误和警告。
E_ERROR
致命运行错误,脚本停止。
E_WARNING
运行时警告,脚本继续。
E_NOTICE
运行时注意,比如未定义变量。
七、常见坑
坑1:改了php.ini不生效
改的不是实际加载的那个php.ini。
解决: 用 php --ini 看实际加载的是哪个。
坑2:FPM和CLI的php.ini不一样
命令行改了,网页上不生效。
原因: CLI和FPM用不同的php.ini。
解决: 改FPM的那个,比如 /etc/php/7.4/fpm/php.ini。
坑3:页面白屏
可能是语法错误,php.ini都没加载起来。
检查: 看PHP错误日志。
坑4:开了错误显示有安全风险
生产环境不能开!
注意: 排查完一定要改回去。
坑5:.htaccess里覆盖了
有些主机在.htaccess里设了php_flag。
检查: 看看.htaccess里有没有。
八、生产环境配置
生产环境不要开display_errors,但要开日志:
display_errors = Off
log_errors = On
error_log = /var/log/php_errors.log
error_reporting = E_ALL & ~E_NOTICE & ~E_DEPRECATED
九、查看错误日志
PHP错误日志
tail -f /var/log/php_errors.log
Nginx错误日志
tail -f /var/log/nginx/error.log
Apache错误日志
tail -f /var/log/httpd/error_log
十、快速排查
第一步:代码里临时开
ini_set('display_errors', 1);
error_reporting(E_ALL);
第二步:看具体报错
刷新页面,看报什么错。
第三步:解决完删掉
改完了把代码里的ini_set删掉,或者改回生产配置。
总结
记住:
display_errors = On显示错误error_reporting = E_ALL显示所有错误- 改完重启php-fpm
- 生产环境关掉display_errors,开log_errors
- 代码里可以用ini_set临时开
开发环境推荐:
display_errors = On
error_reporting = E_ALL
log_errors = On
生产环境推荐:
display_errors = Off
log_errors = On
error_reporting = E_ALL & ~E_NOTICE
遇到问题加QQ23979811 协助处理
Nginx 403 Forbidden权限不足原因与解决
前言
打开网站突然报 403 Forbidden,权限不足。这是 Nginx 最常见的报错之一。本文讲一下 403 的常见原因和解决办法。
403 是什么意思
403 Forbidden 表示服务器理解请求,但拒绝执行。说白了就是 Nginx 不让你访问这个文件/目录。
常见原因和解决办法
原因1:文件/目录权限不对
最常见的原因。Nginx 运行的用户(一般是 www)没有权限读文件。
检查权限:
ls -l /var/www/html/index.html
如果是 644 以下,或者属主是 root,Nginx 就读不了。
解决:
# 改文件权限
chmod 644 /var/www/html/index.html
# 改目录权限
chmod 755 /var/www/html
# 改属主
chown -R www:www /var/www/html
原因2:首页文件不存在
访问网站根目录,但没有 index 首页文件。
检查:
ls /var/www/html/
看看有没有 index.html 或 index.php。
解决:
- 把首页文件名改成 index.html 或 index.php
- 或者在 Nginx 配置里指定 index
index index.html index.php;
原因3:目录没有索引权限
访问一个目录,目录里没有首页文件,Nginx 又没开目录列表。
解决方法一: 放一个 index.html 进去
解决方法二: 开目录列表(不推荐,不安全)
location /uploads/ {
autoindex on;
}
原因4:SELinux 没关
CentOS7 默认开了 SELinux,会拦截 Nginx 访问文件。
检查 SELinux 状态:
getenforce
如果是 Enforcing,说明开着。
解决:
# 临时关闭
setenforce 0
# 永久关闭
vi /etc/selinux/config
# 改成 SELINUX=disabled
原因5:Nginx 配置了访问控制
Nginx 配置里限制了 IP 访问,或者需要密码。
检查配置:
grep -i "deny\|allow\|auth_basic" /etc/nginx/conf.d/*.conf
如果有 deny all 或者 IP 白名单,把你的 IP 加上或者去掉限制。
原因6:文件路径不对
Nginx 配置的 root 路径和实际文件路径不一致。
检查配置:
grep root /etc/nginx/conf.d/*.conf
确认 root 指向的目录里确实有你的文件。
排查步骤
- 先看错误日志
tail -f /var/log/nginx/error.log
日志里会写得很清楚是什么原因。
- 检查文件权限
ls -l /var/www/html/
- 检查 SELinux
getenforce
- 检查 Nginx 配置
nginx -t
常见坑
坑1:只改了文件权限没改目录权限
文件权限是 644,但上级目录权限不对,Nginx 还是进不去。
解决: 一级一级改目录权限:
chmod 755 /var
chmod 755 /var/www
chmod 755 /var/www/html
坑2:上传的文件是 root 创建的
用 root 上传了文件,文件属主是 root,Nginx 用户读不了。
解决:
chown -R www:www /var/www/html
坑3:SELinux 改了没重启
临时关了 SELinux,但重启服务器又开了。
解决: 改配置文件永久关闭,别只 setenforce 0。
坑4:用了 CDN 或 WAF
前面有 CDN 或 WAF,它们拦截了请求。
解决: 直接用服务器 IP 访问,看看是不是还是 403。如果直接 IP 访问没问题,就是 CDN/WAF 的问题。
总结
| 原因 | 解决办法 |
|---|---|
| 文件权限不对 | chmod 644 文件、chmod 755 目录 |
| 首页不存在 | 放个 index.html 进去 |
| SELinux 拦截 | 关闭 SELinux |
| IP 被限制 | 检查 Nginx allow/deny 配置 |
| 路径不对 | 检查 root 配置 |
| 属主不对 | chown www:www 目录 |
记住: 403 先看错误日志,大部分问题日志里都写得很清楚。
遇到问题加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 协助处理