要对 nginx + fastcgi 的动态请求做精细化耗时分析,核心是同时记录 $request_time、$upstream_response_time、$upstream_connect_time 和 $msec 四个变量,通过其数值关系精准定位瓶颈:若 $request_time ≈ $upstream_response_time(差值 50ms,需检查 php-fpm 连接池或 socket 配置,并结合 php-fpm 慢日志按 $msec 交叉验证。

要对 Nginx + FastCGI(如 PHP-FPM)的动态请求做精细化耗时分析,核心是把请求链路中各阶段时间拆解记录进访问日志,再结合状态码与上下文定位瓶颈。关键不在于“开启日志”,而在于选对变量、分清阶段、避免误读。
必须记录的四个耗时变量
在 log_format 中同时包含以下变量,才能完整还原一次 PHP 请求的生命周期:
- $request_time:总耗时(秒,毫秒精度),从收到第一个字节到发完最后一个响应字节,含上传、Nginx 处理、FastCGI 响应、网络发送全过程
-
$upstream_response_time:FastCGI 实际处理耗时(即 PHP-FPM 执行时间),单位相同,仅在
fastcgi_pass生效时有值;多台后端会以逗号分隔 - $upstream_connect_time:Nginx 连接 PHP-FPM 的耗时(TCP 握手、Unix socket 建立等),可判断连接池或 socket 配置问题
- $msec:日志写入时刻的时间戳(秒+毫秒),便于与 PHP-FPM 慢日志、应用层埋点对齐
推荐的 log_format 配置示例
在 http{} 块中定义(注意空格与引号):
然后在启用 FastCGI 的 location ~ \.php$ 块中指定:
不要在全局 server 块用这个格式——静态资源没有 upstream,会导致 $upstream_* 字段为空或“-”,干扰解析。
区分真实瓶颈的判断逻辑
看日志行中三个时间字段的关系:
- 若
$request_time ≈ $upstream_response_time(差值 - 若
$upstream_response_time正常(如 0.02s),但$request_time很大(如 2.5s),问题可能出在:客户端上传慢(大文件 POST)、Nginx 缓冲区不足、或响应体过大且未启用gzip或sendfile - 若
$upstream_connect_time显著偏高(如 > 50ms),需检查 PHP-FPM 的pm.max_children是否过载、socket 路径权限、或是否误配了 TCP 连接(如用了 127.0.0.1:9000 却没开对应端口)
配合 PHP-FPM 慢日志交叉验证
Nginx 日志只告诉你“慢”,PHP-FPM 慢日志能告诉你“为什么慢”。确保 PHP-FPM 配置中启用了:
slowlog = /var/log/php-fpm-slow.logrequest_slowlog_timeout = 1s
当 Nginx 日志中某请求 $request_time 达到 1.2s,就去慢日志里按 $msec 时间戳前后 1 秒范围搜索,基本能定位到具体脚本和调用栈。











