Nginx 返回 502 Bad Gateway 且日志提示 PHP-FPM 进程崩溃,通常是因为 PHP 脚本消耗内存超过限制或被系统 OOM Killer 强制终止。处理重点在于排查系统日志确认进程退出原因,并调整 PHP-FPM 进程管理参数与 PHP 内存限制。
先说结论:PHP-FPM 进程意外退出导致 Nginx 无法连接到上游服务,需优先区分是代码缺陷还是资源不足。
- 先确认:检查系统 dmesg 日志确认是否触发 OOM Killer 杀死 PHP 进程。
- 先处理:调整 php-fpm.conf 中 pm.max_children 及 php.ini 中 memory_limit 参数。
- 再验证:重启服务后监控错误日志,确认不再出现 child exited 记录。
命令速用版
以下命令用于快速定位进程退出原因和服务状态,需在服务器终端以 root 或 sudo 权限执行。
# 查看 Nginx 错误日志最后 50 行
tail -n 50 /var/log/nginx/error.log
# 检查系统内核日志是否包含 OOM 杀死进程记录
dmesg | grep -i "kill"
# 查看 PHP-FPM 进程状态
systemctl status php-fpm
# 重启 PHP-FPM 服务
systemctl restart php-fpm为什么会这样
Nginx 作为反向代理服务器,当上游 PHP-FPM 进程在处理请求时意外终止,Nginx 会因连接断开而返回 502 错误。
PHP-FPM 进程崩溃常见于脚本执行内存超过 php.ini 设定的 memory_limit,或者服务器物理内存不足触发 Linux 内核的 OOM Killer 机制。此外,代码中存在死循环或调用不存在扩展函数也可能导致段错误(segfault)使进程退出。
分步处理
按照以下顺序排查,每步操作后需观察日志变化。
1. 确认进程退出原因
查看系统日志 /var/log/messages 或使用 dmesg 命令。如果看到 Out of memory: Kill process 字样,说明是内存不足导致。如果 Nginx 错误日志显示 upstream prematurely closed connection,说明 PHP 端主动断开或崩溃。
2. 调整 PHP 内存限制
编辑 php.ini 文件,找到 memory_limit 参数。如果当前值较小且脚本确实需要更多内存,适当调大该值。注意不要超过服务器物理内存总量。
3. 优化 PHP-FPM 进程管理
编辑 php-fpm 池配置文件(通常位于 /etc/php-fpm.d/www.conf 或 /etc/php/版本/fpm/pool.d/www.conf)。检查 pm.max_children 设置,如果设置过大导致内存耗尽,应减小该值。建议将 pm 模式设置为 dynamic 或 ondemand,避免 static 模式占用过多空闲内存。
4. 设置请求超时保护
在 PHP-FPM 池配置中设置 request_terminate_timeout,防止单个脚本无限运行占用进程。同时确认 Nginx 配置中 fastcgi_read_timeout 设置合理,避免 Nginx 过早断开连接。
怎么验证是否生效
操作完成后,访问之前报错的页面,观察是否恢复正常。
查看 Nginx 错误日志,确认不再频繁出现 upstream prematurely closed connection 或 connect() failed (111: Connection refused) 错误。
使用 top 或 htop 命令观察 PHP-FPM 进程内存占用是否稳定,确认没有进程被系统强制杀死。
常见坑
盲目调大 memory_limit 可能导致服务器整体内存耗尽,引发更严重的系统崩溃。
忽略代码层面的内存泄漏,仅靠增加资源只能暂时掩盖问题,长期运行仍会崩溃。
修改配置后未重启 PHP-FPM 服务,导致新配置未生效。
常见问题
502 错误和 504 错误有什么区别?
502 表示上游服务器返回了无效响应或连接断开,504 表示上游服务器处理超时未返回结果。
如何查看 PHP-FPM 的独立日志?
在 php-fpm.conf 配置文件中启用 catch_workers_output 并设置 error_log 路径,通常在 /var/log/php-fpm/error.log。
增加服务器内存一定能解决 502 吗?
不一定,如果是代码死循环或逻辑错误导致的崩溃,增加内存无法解决问题,需修复代码。