502 Bad Gateway 的六种成因
502 是最常见也最容易吓人的错误。它本身信息量很少,但配合日志就能快速定位。
先看日志
所有排查从这里开始:
tail -n 100 /www/wwwlogs/nginx_error.log
日志里的关键词直接对应下面的成因。
一、PHP-FPM 没在跑
日志特征:connect() failed (111: Connection refused)
systemctl status php-fpm
systemctl restart php-fpm
如果启动失败,看 PHP 的错误日志——通常是配置文件语法错误。
二、进程数不够
日志特征:server reached pm.max_children setting
访问量上来了,进程池被占满。改 php-fpm.d/www.conf:
pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
:::tip max_children 怎么算
可用内存 ÷ 单进程内存。单进程一般 30-50MB,所以 2G 内存的机器设 40 左右比较合适。设太大反而会因为内存耗尽而更糟。
:::
三、执行超时
日志特征:upstream timed out
某个请求跑太久。两边都要改:
# php.ini
max_execution_time = 300
# nginx
fastcgi_read_timeout 300;
但更该做的是找出为什么这么慢——通常是某个没加索引的查询。
四、内存耗尽
日志特征:日志里可能什么都没有,但 dmesg 里有 OOM 记录
dmesg | grep -i "out of memory"
free -h
解法是加内存、加 swap,或者降低 pm.max_children。
五、磁盘满了
日志特征:各种奇怪的写入失败
df -h
df -i # inode 也可能满,别忘了查
日志文件是最常见的空间杀手。
六、文件锁死
日志特征:请求全部卡住直到超时,进程数飙升
这种情况比较隐蔽:某个进程拿着文件锁不放,后续请求全部排队。
:::danger 网络挂载的目录尤其危险
如果站点目录挂在 NFS / SMB 上,flock 可能会永久卡死。表现就是整站 502 而且重启 PHP 也不好使。
解法:把需要频繁加锁的运行时目录放到本地磁盘,别放网络挂载上。 :::
快速处置
线上出 502 时,先恢复服务再查原因:
systemctl restart php-fpm nginx
重启能解决前四种。如果重启后几分钟又出现,那是第五或第六种,需要真正定位。
评论 0