slowlog 配置需同时满足三条件才生效:slowlog 指向存在且 php-fpm 用户有写权限的绝对路径、request_slowlog_timeout 设为非零值(如2s)、二者均置于 pool 段内;修改后须执行 php-fpm -t && systemctl reload php-fpm。

slowlog 配置必须同时满足三个条件才生效
只写 slowlog = /var/log/php-fpm-slow.log 没用,缺一不可:
-
slowlog指向绝对路径,且目录存在、www-data(或 PHP-FPM 运行用户)有写权限 -
request_slowlog_timeout设为具体值(如2s),不能是0或注释状态 - 这两项必须放在 pool 段内(如
[www]块中),不能只写在全局php-fpm.conf里
改完务必执行 php-fpm -t && systemctl reload php-fpm,否则配置不加载。常见现象是日志文件为空——八成是权限不对或配置没 reload。
慢日志里真正有用的不是时间戳,而是 backtrace 行
一条典型记录长这样:
[12-Oct-2024 14:22:36] [pool www] pid 12345 script_filename = /srv/www/example.com/public/index.php [0x00007f8a1b2c3d40] sleep() /srv/www/example.com/app/helpers/DebugHelper.php:42 [0x00007f8a1b2c3e50] processRequest() /srv/www/example.com/public/index.php:18
关键信息在方括号里的函数调用链:
- 最上面一行是当前阻塞点:
sleep()发生在DebugHelper.php第 42 行 - 下一行是它的调用者:
processRequest()在入口文件第 18 行触发了它 - 注意:backtrace 是从深往浅回溯,不是从上往下执行顺序
别被 script_filename 迷惑——它只是请求入口,真正卡住的可能在某个 helper、service 或第三方 SDK 里。
区分 PHP 执行慢和外部依赖慢
slowlog 只捕获 PHP 进程内耗时,不包括:
- Nginx 转发延迟、TLS 握手、网络抖动
- MySQL 连接建立时间(但连接后执行 SQL 的耗时算在内)
- cURL 等同步 I/O 的等待时间(
curl_exec()会完整计入)
所以看到 curl_exec() 出现在 backtrace 顶部,说明卡在远程 HTTP 请求;看到 mysqli_query() 或 PDO::query(),就得查对应 SQL 是否走索引、是否锁表;而 file_get_contents() 或 fopen() 则指向本地文件 I/O 阻塞(比如 NFS 挂载异常)。
线上环境阈值别设太高,2s 是合理起点
设 request_slowlog_timeout = 30s 几乎等于没开——多数真实卡顿发生在 3–8s 区间,30s 才触发只会漏掉大量问题。
- 开发/预发环境建议从
1s开始,快速暴露低效逻辑 - 线上可设
2s,配合 Nginx 的$request_time日志交叉验证:如果 Nginx 记录耗时 5s,但 slowlog 没记录,说明瓶颈在 PHP 外部(如 upstream、DNS、TCP 建连) - 日志量大时加
logrotate,避免单个 slow.log 超过 1GB 卡死磁盘
backtrace 不带变量值、不显示 SQL 内容,它只告诉你“哪一行哪个函数卡住了”。要定位深层原因,得顺着那行代码查上下文——比如 sleep(5) 是调试残留,还是某 SDK 内部重试逻辑失控。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











