502 Bad Gateway根因需通过代理日志定位:重点查error.log中upstream相关错误(如“Connection refused”“upstream timed out”),结合upstream_status、系统日志及进程状态交叉验证,而非仅看客户端502。

直接看 error.log 里带 upstream 和 connect、read、send 关键词的错误行,重点识别是否频繁出现 502 Bad Gateway 及其前置原因——这通常不是 CGI 自身崩溃的直接记录,而是 Nginx 在与 CGI(如 php-cgi、fcgiwrap)通信失败后留下的“结果日志”。真正定位 CGI 异常退出,需结合 error.log 中的连接中断线索、系统级日志和进程行为交叉验证。
抓取 error.log 中 upstream 失败的典型模式
Nginx 不会直接记录“php-cgi 进程已退出”,但会如实反映与之通信失败的瞬间:
-
Connection refused:说明 CGI 进程未在监听端口或 socket 文件不存在,常见于守护进程意外终止后未重启,例如:
[error] 12345#67890: *112 connect() failed (111: Connection refused) while connecting to upstream - Connection reset by peer:CGI 进程在 Nginx 发送请求后立即关闭连接,多因 CGI 启动即崩溃、配置错误(如 PHP ini 中内存限制过小)、或收到非法请求后异常退出
- upstream timed out:不是超时本身导致退出,而是 CGI 响应缓慢或卡死的表象;若伴随大量同类日志且 CGI 进程数持续下降,提示其可能反复启动又闪退
- 注意日志中的
upstream: "fastcgi://...后缀,确认你配置的是 TCP 端口还是 Unix socket;路径错误(如 socket 文件权限不对或路径拼错)会导致稳定性的Connection refused
关联 system 日志和进程状态验证退出事实
仅靠 error.log 无法确认 CGI 是“挂了”还是“没起来”,必须补全上下文:
- 查 systemd 服务状态(若 CGI 封装为 service):
systemctl status php-fpm或systemctl status fcgiwrap,观察是否显示inactive (dead)或failed,并用journalctl -u php-fpm -n 50看其自身崩溃原因(如段错误、OOM、配置加载失败) - Windows 下若用 nssm 托管 php-cgi,查看 Windows 事件查看器中对应服务日志,或运行
nssm status php检查实时状态 - Linux 手动启停场景:用
ps aux | grep php-cgi对比请求前后进程是否存在;若进程号不连续、存活时间极短(
检查 CGI 自身配置与资源限制
CGI 进程退出往往源于自身运行环境问题,Nginx 日志只是“回声”:
-
PHP-FPM 场景:检查
www.conf中pm.start_servers、pm.max_children是否合理;rlimit_files是否低于 Nginx 的worker_rlimit_nofile;catch_workers_output = yes可捕获 worker stderr 输出到 FPM 日志,有助于发现脚本 fatal error -
通用资源瓶颈:CGI 进程被 OOM Killer 杀掉时,
dmesg | grep -i "killed process"会明确写出进程名(如php-cgi);同时检查磁盘空间(df -h),满载时 CGI 写临时文件或 session 失败也会触发退出 -
权限与路径问题:确保 CGI 可执行文件路径正确、有执行权限;socket 文件目录(如
/var/run/php/)存在且 Nginx worker 用户(如www-data)可读写;使用namei -l /var/run/php/php7.4-fpm.sock逐级验证权限链
启用调试辅助:临时加一层可观测性
当常规日志信息不足时,主动制造线索:
- 在 CGI 启动命令前加日志输出,例如 php-fpm 启动脚本中插入:
echo "$(date): Starting php-fpm" >> /var/log/php-start.log
并在php-fpm.conf中配置error_log = /var/log/php-fpm-error.log - 对 fastcgi_pass 使用
fastcgi_next_upstream error timeout http_502;并配合log_format记录 upstream_addr 和 upstream_status,可统计 502 是否集中指向某一个 backend 实例 - 如怀疑是单个脚本导致崩溃,开启 PHP 的
display_errors = On和log_errors = On,让错误落地到 PHP 错误日志而非静默消失


















