php-fpm不记录sql慢查询,但可通过配置slowlog和request_slowlog_timeout捕获超时php请求的完整调用栈;需在pool段设置slowlog路径、阈值(如5s),并重载服务生效。

PHP-FPM 本身不直接记录“慢查询日志”,它没有类似 MySQL 的 slow_query_log 机制;但可以通过配置 slowlog 功能,捕获执行时间超过阈值的 PHP 脚本调用栈(即“慢请求”),这是定位性能瓶颈的关键手段。
开启 PHP-FPM 的 slowlog
在 PHP-FPM 的 Pool 配置中(如 www.conf)启用以下参数:
-
slowlog:指定慢日志文件路径,例如
slowlog = /var/log/php-fpm/www-slow.log -
request_slowlog_timeout:设置触发慢日志的执行时长阈值,例如
request_slowlog_timeout = 5s(支持 s/m/h 单位) -
request_terminate_timeout(可选):超时后强制终止请求,避免阻塞 worker,例如
request_terminate_timeout = 30s
⚠️ 注意:slowlog 是 per-pool 的,需在对应 pool 段内配置;修改后需重载 PHP-FPM(systemctl reload php-fpm 或 kill -USR2 主进程)。
理解 slowlog 输出内容
慢日志每条记录包含三部分:
- 时间戳与请求基本信息(客户端 IP、URI、请求方法)
- 执行耗时(如
script_filename = /var/www/index.php,[pool www] pid 12345) -
完整调用栈(backtrace):从
main()开始逐层向下,标出每个函数调用及所在文件行号,例如:[0x00007f8b9c0a1234] mysqli_query() /var/www/db.php:42[0x00007f8b9c0a1235] get_user_data() /var/www/user.php:18
调用栈是分析核心——它能暴露深层嵌套、未加索引的数据库查询、同步远程 API 调用、或低效循环等典型问题。
常见慢请求原因与排查建议
结合 slowlog 中的 backtrace,重点关注以下模式:
-
数据库操作耗时高:检查
mysqli_query、PDO::query或 ORM 方法是否缺少索引、使用了SELECT *、存在 N+1 查询 -
外部 HTTP 请求阻塞:如
file_get_contents("https://...")、curl_exec()未设超时,应改用异步或加curl_setopt($ch, CURLOPT_TIMEOUT, 3) -
大数组/字符串处理:如
json_encode($huge_array)、array_merge_recursive()在大数据量下指数级变慢 - 未捕获的异常或递归过深:backtrace 显示大量重复函数名,可能是无限递归或异常反复重试
配合其他工具提升分析效率
slowlog 是起点,不是终点:
- 搭配 APCu 或 XHProf/Xdebug Profiler 获取更细粒度函数耗时(而不仅是栈帧)
- 用 strace -p
观察慢请求期间的系统调用(如频繁 read/write、futex 等待) - 检查 Web 服务器(Nginx/Apache)access log 中对应请求的
$request_time,确认延迟是否来自 PHP 层还是网络/代理 - 对高频慢 URI 做 监控告警(如用 Logstash + Elasticsearch + Kibana 统计 slowlog 出现频次)
不复杂但容易忽略:确保 slowlog 文件目录可写、磁盘未满,并定期轮转(可用 logrotate),否则日志会写失败且无提示。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











