Linux 上排查 PHP-FPM 故障的实用流程
一 快速判定与定位
sudo systemctl status php<版本>-fpm,关注是否出现 active (running) 或 failed,以及 journalctl -xeu php<版本>-fpm 的最新报错。pgrep php-fpmss -lntp | grep php 或 netstat -plnt | grep phpls -l /var/run/php/php<版本>-fpm.socksudo php-fpm<版本> -t(或 php-fpm -t,取决于 PATH),确保配置无语法错误。/var/log/php<版本>-fpm.log、/var/log/php-fpm.log、/var/log/php/<版本>/fpm.log 或自定义路径;使用 tail -f 实时观察。www.conf 中确认 pm.status_path(如 /status),访问 http://localhost/status 检查 pool、processes、idle/active 等状态是否正常。二 常见故障与修复对照表
| 症状 | 快速检查 | 修复建议 |
|---|---|---|
| 服务无法启动 | systemctl status、journalctl、php-fpm -t |
修正配置语法;若报 Permission denied,确保日志/运行目录对 运行用户(如 www-data、nginx、apache) 可写;必要时 chown/chmod 并重启 |
| 端口被占用(如 9000) | `ss -lntp | grep 9000` |
| Unix 套接字不存在/权限错误 | ls -l /var/run/php/php*.sock |
确认 listen 与 Nginx/前置代理一致;检查 socket 目录权限与属主;必要时 systemctl restart php-fpm 重建 |
| 权限/SELinux 导致初始化失败 | 日志出现 failed to open error_log: Permission denied | 修正日志/目录属主与权限;若启用 SELinux,临时 setenforce 0 验证,定位后用 chcon 设置正确类型并恢复 Enforcing |
| 502/504 网关错误 | 访问返回 502/504,FPM 进程存在或队列满 | 检查 FPM 与 Nginx 的 listen/pass 路径或端口一致;查看 慢日志与 进程占用;必要时调大 pm.max_children、listen.backlog 并优化慢请求 |
三 性能与慢请求定位
slowlog = /var/log/php-fpm/slow.logrequest_slowlog_timeout = 1s(按需调整为 1000ms 等)sudo systemctl restart php<版本>-fpmtail -f /var/log/php-fpm/slow.log四 配置与运维要点
五 一键排查脚本示例
#!/usr/bin/env bash
set -Eeuo pipefail
PHP_VER=$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')
FPM_SERVICE="php${PHP_VER}-fpm"
FPM_POOL="/etc/php/${PHP_VER}/fpm/pool.d/www.conf"
SOCK_PATH=$(grep -E '^listen\s*=' "$FPM_POOL" | awk '{print $3}' | head -n1)
LOG_ERR=$(grep -E '^error_log\s*=' "$FPM_POOL" | awk '{print $3}' | head -n1)
LOG_SLOW=$(grep -E '^slowlog\s*=' "$FPM_POOL" | awk '{print $3}' | head -n1)
echo "=== $FPM_SERVICE 状态 ==="
systemctl is-active --quiet "$FPM_SERVICE" && echo "active" || { echo "inactive"; journalctl -xeu "$FPM_SERVICE" | tail -n50; exit 1; }
echo -e "\n=== 进程与监听 ==="
pgrep -a php-fpm || echo "无 php-fpm 进程"
ss -lntp | grep -E "php|9000|$SOCK_PATH" || echo "未检测到监听"
echo -e "\n=== 配置语法 ==="
php-fpm${PHP_VER} -t
echo -e "\n=== 关键文件与权限 ==="
ls -ld "$(dirname "$SOCK_PATH")" 2>/dev/null || echo "Socket 目录不存在: $(dirname "$SOCK_PATH")"
[ -n "$LOG_ERR" ] && ls -l "$LOG_ERR" 2>/dev/null || echo "错误日志未配置或不存在: $LOG_ERR"
[ -n "$LOG_SLOW" ] && ls -l "$LOG_SLOW" 2>/dev/null || echo "慢日志未配置或不存在: $LOG_SLOW"
echo -e "\n=== SELinux 状态 ==="
getenforce 2>/dev/null || echo "SELinux 未安装"
echo -e "\n=== 提示 ==="
echo "若 Nginx 报 502/504,请核对 fastcgi_pass 与 FPM 的 listen 一致,并查看慢日志与进程占用。"
将脚本保存为 check_fpm.sh,执行:chmod +x check_fpm.sh && sudo ./check_fpm.sh。