php-fpm slowlog精准捕获php脚本执行阶段超时,仅记录从worker接收请求到脚本退出的纯执行耗时,不包含nginx、网络或mysql连接建立时间;必须配置在pool段(如www.conf内[www]下),含slowlog路径、request_slowlog_timeout(如2s)及权限校验,配合mysql慢日志交叉验证才能准确定位瓶颈。

PHP慢请求不是“SQL慢”或“页面慢”的模糊感觉,而是能精确到某次请求、某个函数调用、某一行代码的执行超时。关键在于区分清楚:php-fpm slowlog 抓的是 PHP 脚本执行阶段的卡点,不包含 Nginx 耗时、网络延迟、MySQL 连接建立时间——它只记录从 php-fpm worker 接收请求开始,到脚本退出为止的纯执行耗时。
php-fpm slowlog 配置必须写在 pool 段里
很多人改了 php.ini 或全局 php-fpm.conf 却没日志,就是因为配置位置错了。它必须出现在 Pool 配置文件中(如 /etc/php/8.5/fpm/pool.d/www.conf),且在 [www] 段内:
-
slowlog = /var/log/php-fpm/www-slow.log—— 路径父目录必须存在,且属主为www-data(Ubuntu/Debian)或nginx(CentOS/RHEL) -
request_slowlog_timeout = 2s—— 分号必须删掉;单位支持s和m,但不支持ms(500ms是非法写法) -
request_terminate_timeout = 0(可选但推荐)—— 防止死循环脚本一直占着 worker 不释放
改完务必执行 php-fpm -t && systemctl reload php8.5-fpm,否则配置不生效。
验证 slowlog 是否真在工作
别等线上出问题才查。立刻建一个测试脚本:
<?php sleep(3); ?>
确保 request_slowlog_timeout 设为 2s(比 sleep(3) 小),访问一次后运行:
tail -n 10 /var/log/php-fpm/www-slow.log
看到类似这样的输出才算成功:
[12-Oct-2024 14:22:36] [pool www] pid 12345 script_filename = /var/www/html/slow-test.php [0x00007f8a1b2c3d40] sleep() /var/www/html/slow-test.php:1
如果日志为空,90% 是路径权限不对或分号没删干净。
从 backtrace 定位真实瓶颈类型
slowlog 的核心价值是 backtrace,但它不告诉你“为什么卡”,只告诉你“卡在哪”。需要结合上下文判断:
- 看到
curl_exec()或file_get_contents()卡住 → 检查是否漏设CURLOPT_TIMEOUT,DNS 解析慢可加CURLOPT_DNS_CACHE_TIMEOUT - 看到
PDO::query()、mysqli_query()卡住 → 不代表 SQL 慢,可能是连接池耗尽、远程数据库不可达、或表被长事务锁住;先用mysqladmin ping或telnet db-host 3306测试连通性 - 看到大量重复函数名(如连续十几行
get_user())→ 很可能是无限递归、异常未捕获导致重试、或缓存穿透引发的雪崩调用
注意:slowlog 不记录变量值、不反映 MySQL 的 Lock_time(那个在 MySQL 慢日志里),也不区分 CPU 密集型还是 I/O 等待型卡顿——它只是第一道精准定位入口。
slowlog 和 MySQL 慢查询日志必须配合看
一个请求慢,可能有多个环节叠加:PHP 脚本里调了 5 次 PDO::query(),其中第 3 次执行了 4 秒,但 slowlog 只显示“卡在第 3 行 query()”,而真正原因可能是这条 SQL 在 MySQL 里触发了全表扫描 + Using filesort。这时候必须:
- 从
slowlog找到卡住的脚本路径和行号 - 去对应 PHP 文件里提取实际执行的 SQL(注意预处理语句要还原参数,不能只看带
?的模板) - 拿这条 SQL 去 MySQL 执行
EXPLAIN FORMAT=TRADITIONAL,重点看type、key、rows、Extra - 再回查 MySQL 慢日志,确认该 SQL 的
Query_time和Rows_examined是否匹配
单独看任一端都容易误判。比如 slowlog 显示某次请求总耗时 6 秒,backtrace 显示卡在 PDO::query(),但 MySQL 慢日志里查不到这条 SQL —— 那大概率是连接超时或认证失败,根本没走到执行阶段。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











