php-fpm slowlog可精准捕获php脚本执行阶段超时(从worker接收请求到脚本退出的纯耗时),必须配置在pool段(如www.conf的[www]下),含slowlog路径、request_slowlog_timeout(如2s)及request_terminate_timeout,配合nginx和mysql日志交叉验证才能准确定位瓶颈。

PHP 8.2 高并发下出现慢请求,不能只盯着代码或 SQL 猜——关键要靠 php-fpm slowlog 精准捕获真实卡点。它记录的是从 worker 接收请求到脚本退出的纯执行耗时,不含 Nginx、网络延迟、MySQL 连接建立等外部时间,因此是定位 PHP 层瓶颈最直接的证据。
slowlog 必须配在 pool 段里才生效
很多人配置了却没日志,根本原因是写错了位置。它不能放在 php.ini 或全局 php-fpm.conf 中,必须写在 Pool 配置文件内(如 /etc/php/8.2/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,500ms 是非法写法;分号必须删掉
- request_terminate_timeout = 30s(推荐):防止死循环或卡死的 cURL 占着 worker 不放
改完务必执行 php-fpm -t && systemctl reload php8.2-fpm,否则配置不加载。
用测试脚本快速验证 slowlog 是否工作
别等线上出问题再试。建一个 /var/www/html/test-slow.php:
<?php sleep(3); ?>
确保 request_slowlog_timeout = 2s,访问一次后运行:
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/test-slow.php [0x00007f8a1b2c3d40] sleep() /var/www/html/test-slow.php:1
如果日志为空,90% 是权限不对或分号残留。
从 backtrace 看懂“卡在哪”,而不是“为什么卡”
slowlog 的核心价值是调用栈(backtrace),但它不解释原因,只暴露位置。需结合上下文判断类型:
- 看到 curl_exec()、file_get_contents() 卡住 → 检查是否漏设 CURLOPT_TIMEOUT,DNS 慢可加 CURLOPT_DNS_CACHE_TIMEOUT
- 看到 PDO::query()、mysqli_query() 卡住 → 不代表 SQL 慢,可能是连接池耗尽、远程 DB 不可达、表被锁、或 PDO 连接未复用
- 看到 json_decode()、unserialize() 卡住 → 大对象反序列化开销高,尤其嵌套深或数据体积大(边缘设备更敏感)
- 看到 preg_match() 卡住 → 正则回溯风险,检查模式是否含贪婪量词 + 无界匹配
交叉验证才能准确定位瓶颈根因
slowlog 只反映 PHP 执行阶段,必须配合其他日志缩小范围:
- 对比 Nginx access log 的 $request_time 和 $upstream_response_time 差值:若差值大,说明请求在 FPM 队列里排队,不是脚本慢,而是 pm.max_children 不足或 worker 被长期占用
- 查 MySQL 慢日志:若 slowlog 显示 PDO::query 卡住,而 MySQL 慢日志里对应 SQL 执行很快,那问题大概率在连接层(如连接池满、DNS 解析失败)
- 看 FPM status 页面(pm.status_path):关注 listen queue 是否持续非零、max children exceeded 是否频繁计数,确认是否真因资源不足导致排队
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











