一、定位PHP-FPM错误日志文件
PHP-FPM的错误日志路径通常由配置文件决定,默认常见位置包括:
/var/log/php-fpm/error.log/var/log/php-fpm/www-error.log/var/log/php7.x-fpm.log(x为PHP版本号,如7.4、8.2)可通过以下命令快速查找:
sudo find /var/log -name "*php-fpm*log"
若路径未确定,可检查PHP-FPM主配置文件(/etc/php/{version}/fpm/php-fpm.conf)或pool配置文件(/etc/php/{version}/fpm/pool.d/www.conf)中的error_log指令。
二、常用日志查看与分析命令
tail -f命令跟踪日志文件的实时更新,快速捕捉新出现的错误:sudo tail -f /var/log/php-fpm/error.log
grep命令筛选关键词(如“error”“fatal”“warning”),缩小分析范围:sudo grep -i "error" /var/log/php-fpm/error.log # 查找错误信息
sudo grep -i "fatal" /var/log/php-fpm/error.log # 查找致命错误
sudo grep -i "warning" /var/log/php-fpm/error.log # 查找警告信息
sort和uniq命令,统计重复出现的错误次数,定位高频问题:sudo grep "PHP Fatal error" /var/log/php-fpm/error.log | sort | uniq -c | sort -rn
slowlog参数),可通过以下命令分析慢请求:sudo tail -f /var/log/php-fpm/www-slow.log # 慢日志路径需根据配置调整
常用慢日志分析命令(找出执行时间最长的请求):sudo awk '/^.*script_filename.*$/{print $0}' /var/log/php-fpm/www-slow.log | sort -k 10 -nr | head -10
三、常见错误类型及解读
PHP语法/运行时错误:
日志中会出现PHP Fatal error(致命错误,脚本终止)、PHP Warning(警告,脚本继续执行)、PHP Notice(通知,轻微问题)。
示例:
[01-Sep-2023 12:34:56] PHP Fatal error: Uncaught Error: Call to undefined function foo() in /var/www/my_script.php:12
Stack trace:
#0 /var/www/my_script.php(12): foo()
#1 {main}
thrown in /var/www/my_script.php on line 12
解读:脚本/var/www/my_script.php第12行调用了未定义的函数foo(),导致致命错误。
权限问题:
日志中出现Permission denied(权限被拒绝),通常因PHP-FPM进程用户(如www-data)无权访问脚本、目录或套接字文件。
示例:
[01-Sep-2023 12:35:00] WARNING: [pool www] child 1234 said into stderr: "ERROR: Unable to open primary script: /var/www/html/index.php (Permission denied)"
解读:www-data用户无法读取/var/www/html/index.php文件。
端口/套接字冲突:
日志中出现Address already in use(地址已被使用)或socket already in use(套接字已被使用),因PHP-FPM监听的端口或套接字被其他进程占用。
示例:
[01-Sep-2023 12:35:05] ERROR: unable to bind listening socket for address '/run/php/php7.4-fpm.sock': Address already in use
[01-Sep-2023 12:35:05] ERROR: FPM initialization failed
解读:/run/php/php7.4-fpm.sock套接字已被其他进程占用,导致PHP-FPM无法启动。
资源限制:
日志中出现pm.max_children reached(进程数达到上限)、Allowed memory size exhausted(内存耗尽)或unable to create new process(无法创建新进程),因资源不足导致请求无法处理。
示例:
[01-Sep-2023 12:35:10] WARNING: [pool www] server reached pm.max_children setting (50), consider raising it
解读:当前进程数已达pm.max_children设置的50,需增加该值以处理更多并发请求。
扩展加载失败:
日志中出现Unable to load dynamic library(无法加载动态库),因PHP扩展未正确安装或配置。
示例:
[01-Sep-2023 12:35:15] WARNING: [pool www] child 1235 said into stderr: "PHP Startup: Unable to load dynamic library 'redis.so' (tried: /usr/lib/php/20210902/redis.so (/usr/lib/php/20210902/redis.so: cannot open shared object file: No such file or directory), /usr/lib/php/20210902/redis.so.so (/usr/lib/php/20210902/redis.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0"
解读:redis.so扩展未找到,需安装或修复该扩展。
四、常见错误解决方法
权限问题:
www-data)对脚本、目录有读写权限:sudo chown -R www-data:www-data /var/www/html # 修改网站目录所有者
sudo chmod -R 755 /var/www/html # 设置目录权限
www.conf中的listen.owner和listen.group设置,确保与进程用户一致:sudo nano /etc/php/{version}/fpm/pool.d/www.conf
# 确认以下两行
listen.owner = www-data
listen.group = www-data
sudo systemctl restart php{version}-fpm
```。
端口/套接字冲突:
netstat或lsof查找占用进程:sudo netstat -tulnp | grep 9000 # 检查端口占用
sudo lsof /run/php/php7.4-fpm.sock # 检查套接字占用
sudo kill -9 <PID> # 替换<PID>为占用进程ID
www.conf中的listen指令(如将端口改为9001或修改套接字路径):sudo nano /etc/php/{version}/fpm/pool.d/www.conf
# 修改为
listen = 127.0.0.1:9001 # 或 listen = /run/php/php7.4-fpm.sock
资源限制:
pm.max_children(进程数):根据服务器内存调整(如每进程占用100MB内存,1GB内存可设为10):sudo nano /etc/php/{version}/fpm/pool.d/www.conf
pm.max_children = 50 # 根据实际情况调整
memory_limit(内存限制):修改php.ini文件:sudo nano /etc/php/{version}/fpm/php.ini
memory_limit = 256M # 根据实际情况调整
扩展加载失败:
php -m | grep redis # 检查redis扩展是否加载
sudo apt-get install php{version}-redis # 替换<version>为PHP版本号
php.ini中无效的扩展行(如extension=redis.so),或重新安装扩展。配置文件语法错误:
php-fpm -t命令测试配置文件语法:sudo php-fpm{version} -t # 替换<version>为PHP版本号