PHP慢日志怎么分析

wen PHP项目 22

本文目录导读:

PHP慢日志怎么分析

  1. 确认慢日志是否开启及日志位置
  2. 查看慢日志原始内容
  3. 核心分析方法(三步走)
  4. 不同场景的优化建议
  5. 进阶:实时监控与分析
  6. 总结一句话:

分析 PHP 慢日志的核心目的是找出执行时间过长的请求或函数调用,从而定位性能瓶颈,通常有两种情况:一种是 FPM 慢日志(记录了哪个 PHP 文件慢),另一种是 Xdebug/Blackfire 等性能分析工具(记录函数调用堆栈)。

以下以最常用的 PHP-FPM 慢日志(slowlog 为例,提供系统化的分析方法:

确认慢日志是否开启及日志位置

  1. 检查配置文件(通常在 php-fpm.confwww.conf 中):

    # 开启慢日志
    request_slowlog_timeout = 2s   # 超过2秒的请求会被记录(可设1s、5s等)
    slowlog = /var/log/php-fpm/www-slow.log  # 日志文件路径
  2. 查看日志位置

    • 默认路径:/var/log/php-fpm/slow.log/var/log/php/slow.log
    • 如果找不到,执行:php -i | grep slowloggrep -r "slowlog" /etc/php*

查看慢日志原始内容

  • 基本查看命令:

    tail -n 100 /var/log/php-fpm/slow.log
  • 典型日志条目结构:

    [21-Mar-2025 10:30:15]  [pool www] pid 12345
    script_filename = /var/www/html/index.php
    [0x00007f8a8c00d000] curl_exec() /var/www/html/api.php:205
    [0x00007f8a8c00b000] get_remote_data() /var/www/html/api.php:180
    [0x00007f8a8c008000] process_request() /var/www/html/index.php:45

    关键信息解读:

    1. 时间戳:看是否集中在特定时间段(比如数据库高峰、定时任务)。
    2. script_filename:慢请求的入口文件(index.php)。
    3. 堆栈跟踪:从下往上看,最下面的最外层入口,最上面的是最终卡住的函数。重点关注 curl_execfile_get_contentsmysql_query 等耗时的 I/O 或数据库调用。

核心分析方法(三步走)

统计最多的“脚本文件”

看哪些页面/接口最慢:

# 统计慢日志中出现最多的前10个脚本文件
grep "script_filename" /var/log/php-fpm/slow.log | sort | uniq -c | sort -nr | head -10

出现: api.php 出现100次以上,则说明该接口需要优化。

分析具体的“慢函数”模式

频繁出现这些函数,通常意味着:

  • curl_exec / file_get_contents 外部HTTP请求或API调用超时(最多见)。
  • mysql_query / PDO::query 数据库SQL慢查询(需联合MySQL慢日志看)。
  • session_start() 会话文件锁冲突(高并发时常见)。
  • file_put_contents / fwrite 磁盘IO问题或日志写入阻塞。
  • sleep() / usleep() 代码中主动休眠。

技巧: 如果看不懂堆栈中的PHP函数,很可能是使用了ORM框架(如Laravel、ThinkPHP) 的底层调用,此时需关注堆栈中的业务层函数名称(如 getUserListorderPay)。

关联上下文找“罪魁祸首”

  • 请求参数: 慢日志默认不记录GET/POST参数,如果发现是某个接口慢,需在业务代码中临时加日志记录参数。/index.php?page=1000 可能因为分页过大导致查询慢。
  • 时间波动: 如果某天突然慢请求增多,对比日志时间,检查是否上线了新代码,或数据库数据量/连接数是否突增。

不同场景的优化建议

慢日志典型堆栈 大概率原因 针对性排查命令/工具
curl_exec 卡住 外部 API 超时、DNS 解析慢 设置 CURLOPT_TIMEOUT,用 curl -w 测试外部 URL
PDO::query 卡住 SQL 全表扫描、无索引、死锁 开启 MySQL 慢查询日志,EXPLAIN 分析 SQL
fwrite 卡住 日志文件写入频繁、磁盘 IO 高 iostat -x 1await 列,检查 log 目录是否 RAID 或网络盘
sleep() 出现 代码中人为设置了 sleep(常见于轮询) 建议改用队列或定时任务
频繁出现 include/require 文件系统慢(NFS挂载、Windows共享) 改用 OPcache、使用本机磁盘
函数调用很深,全是框架核心代码 框架自身慢(如路由解析、依赖注入) 开启 OPcache、考虑使用单元测试隔离慢分支

进阶:实时监控与分析

如果服务器很多,可以用工具自动化分析:

  1. 监控工具(实时):

    # 实时观察慢日志(类似tail -f)
    tail -f /var/log/php-fpm/slow.log | awk '{print $0}'
  2. 脚本分析(按分钟统计):

    # 统计每分钟慢日志次数
    awk '/^\[/{date=$1} /script_filename/{print date}' slow.log | sort | uniq -c
  3. 工具推荐(生产环境):

    • 阿里云ARMS / 日志服务:自动解析慢日志并生成报表。
    • 开源的 php-fpm-slow-log-parser(Github上有):php-fpm-slow-log-parser.py -f slow.log --top=10 --by-script
    • 结合 strace(临时排查):如果慢日志说卡在 curl,用 strace -p PID 看是否卡在 connectrecv

总结一句话:

script_filename 知道哪个文件慢,看 curl_exec / PDO::query 知道为何而慢,然后对症下药(优化SQL、设置超时、加缓存)。 大多数慢日志问题,最终都归结为外部请求超时或数据库查询过慢。

抱歉,评论功能暂时关闭!