精准定位低效PHP脚本需协同配置request_slowlog_timeout与slowlog,并补充URI、IP等上下文;结合Nginx的upstream_response_time与request_time交叉验证瓶颈;慢日志中重点分析重复调用链、系统调用阻塞及递归加载问题。

要精准定位低效 PHP 脚本,关键不是单纯开启慢日志,而是让 slowlog 与 request_slowlog_timeout 协同工作,并结合真实请求上下文(如 URI、请求方法、执行时间)来缩小排查范围。
确认 PHP-FPM 慢日志开关已启用
在 PHP-FPM 的 Pool 配置文件中(如 /etc/php/8.2/fpm/pool.d/www.conf),确保以下两项非注释且值合理:
- request_slowlog_timeout = 5s:仅当单个请求执行超时才触发记录(推荐从 2–5 秒起步,避免日志爆炸)
- slowlog = /var/log/php8.2-fpm-slow.log:指定独立慢日志路径,避免和 error log 混杂
⚠️ 注意:request_slowlog_timeout 是针对每个请求的总执行时间(含 PHP 执行、I/O 等),不是脚本内某段代码耗时;它不依赖 php.ini 中的 max_execution_time。
补充关键上下文字段,提升可读性
默认慢日志只输出调用栈,但缺少请求标识。可在 pool 配置中添加:
立即学习“PHP免费学习笔记(深入)”;
- slowlog_format = "%s %s %s %s %s %s %s %s"(PHP 8.0+ 支持,旧版本忽略)
- 更实用的是手动追加环境变量:在 pool 配置里加 env[HTTP_X_REAL_IP] = $remote_addr 和 env[REQUEST_URI] = $request_uri,然后在慢日志处理器中通过
$_SERVER['REQUEST_URI']或自定义日志逻辑打印 - 或使用
php_admin_value[error_log]+ 自定义set_error_handler在超时时主动写入带 URI 的日志(适合深度追踪)
配合 Nginx 记录真实耗时与请求信息
Nginx 的 $upstream_response_time 和 $request_time 可交叉验证:
- 在 Nginx
log_format中加入:upstream_response_time $upstream_response_time request_time $request_time - 若
$upstream_response_time显著大于$request_time,说明瓶颈在 PHP-FPM 层;反之则可能是 Nginx 或网络问题 - 把高耗时请求的
$request_uri和$args一并记入 access log,方便和 slowlog 时间戳对齐
分析慢日志时聚焦三类典型线索
打开 /var/log/php8.2-fpm-slow.log 后,重点看:
-
重复出现的函数调用链:比如频繁出现
mysqli_query→pdo->query→ 某个 model::load(),说明数据库查询未优化或 N+1 问题 -
长时间阻塞在系统调用:如
curl_exec、file_get_contents、fsockopen,提示外部依赖超时或未设 timeout -
递归或深度嵌套的 include/require:日志中显示大量
require_once(...)堆叠,可能加载了冗余类或 autoloader 效率低
用 awk '/^.*\[pool www\]/ {print $0; getline; print $0}' /var/log/php8.2-fpm-slow.log | head -20 快速提取最近几条完整堆栈,比翻全文高效。



















