
通过配置php-fpm的慢日志(slowlog),可自动捕获超时执行的php请求堆栈,精准定位`sleep()`、数据库阻塞、未优化循环等隐藏性能瓶颈。
在生产环境中排查PHP脚本“莫名变慢”问题时,逐行搜索sleep()、usleep()、time_nanosleep()或外部I/O等待(如未设超时的cURL、文件锁、Redis阻塞调用)既低效又不可靠。更专业、可持续的方案是启用PHP-FPM内置的慢请求日志(slowlog)机制——它能在请求实际执行时间超过阈值时,自动记录完整的函数调用栈(backtrace),精确到文件名、行号和调用上下文。
✅ 配置步骤(以PHP-FPM pool为例)
编辑对应pool配置文件(如 /etc/php/{version}/fpm/pool.d/www.conf),添加或修改以下两项:
; 指定慢日志存储路径(确保目录存在且PHP-FPM进程有写入权限) slowlog = /var/log/php-fpm/slow.log ; 设定触发慢日志的执行时间阈值(建议从3s起步,按需调整) request_slowlog_timeout = 3s
⚠️ 注意事项: slowlog 路径的父目录(如 /var/log/php-fpm/)必须由 www-data(或PHP-FPM运行用户)可写; 修改后需重启服务:sudo systemctl reload php{version}-fpm; 日志中将包含完整调用栈,例如:[12-Oct-2024 14:22:35] [pool www] pid 12345 script_filename = /srv/www/example.com/public/index.php [0x00007f8a1b2c3d40] sleep() /srv/www/example.com/lib/legacy.php:87 [0x00007f8a1b2c3c90] process_order() /srv/www/example.com/app/controller.php:152
? 日志解读与进阶技巧
- 每条慢日志以 [pool xxx] 开头,紧随其后的是触发慢请求的完整调用链,最上方的栈帧即为阻塞源头(如示例中的 sleep() 调用);
- 若需更高精度(如捕获>100ms的微延迟),可结合 xdebug.profiler_enable_trigger 或现代替代方案(如 Blackfire、Tideways)进行深度性能剖析;
- 对于CLI脚本,慢日志不生效,此时应使用 strace -e trace=nanosleep,sleep,select,poll,recvfrom php script.php 追踪系统调用级阻塞。
✅ 总结
慢日志不是“调试工具”,而是生产环境必备的可观测性基础设施。它无需修改业务代码、不增加运行时开销(仅超时时触发),却能直接暴露被忽略的sleep()、同步API调用、无索引数据库查询等典型性能陷阱。建议所有PHP-FPM部署均开启,并将慢日志接入集中日志系统(如ELK、Loki)实现告警联动。









