$request_time 表示整个请求生命周期耗时,从接收首字节到发送完响应;upstream_response_time 仅记录 Nginx 等待 PHP-FPM 返回响应的时间,不含 Nginx 自身处理及网络传输延迟。

$request_time 和 $upstream_response_time 都能记录耗时,但它们代表的阶段完全不同——用错一个,就完全没法定位 PHP 层瓶颈。
区分 $request_time 和 $upstream_response_time 的实际含义
Nginx 日志里两个时间变量常被混用,但它们捕获的是不同环节:
-
$request_time:从 Nginx 接收到**第一个字节**开始,到**把最后一个响应字节发给客户端**结束。它包含整个请求生命周期:Nginx 自身处理(如重写、限流)、转发给 PHP-FPM、PHP 执行、Nginx 发送响应头/体、TCP 传输延迟等。 -
$upstream_response_time:仅指 Nginx 向 upstream(比如 PHP-FPM)发起请求后,**等待 upstream 返回完整响应所花的时间**。它不包括 Nginx 自身开销,也不含网络传输耗时(如果是本地 socket 则几乎为 0)。
如果你要判断“是 PHP 脚本慢,还是网络或 Nginx 配置拖慢了用户”,必须同时记录这两个值并做差值分析。例如:$request_time - $upstream_response_time > 0.5 就说明 Nginx 层或网络有明显延迟。
phpEnv 下 Nginx 配置 log_format 的关键细节
phpEnv 是 Windows 环境下的集成包(含 Nginx + PHP-FPM),其默认配置通常不启用详细耗时日志。你需要手动修改 nginx.conf(路径类似 C:\phpEnv\nginx\conf\nginx.conf):
立即学习“PHP免费学习笔记(深入)”;
- 在
http块内添加自定义格式(注意不能放在server内):
log_format phpenv_timed '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time';- 在对应
server块中启用该格式:
access_log "C:/phpEnv/nginx/logs/access.log" phpenv_timed;
- 务必确认
location ~ \.php$块中已正确配置fastcgi_pass(指向 phpEnv 的 PHP-FPM socket 或 127.0.0.1:9000),否则$upstream_response_time恒为 “-”。
Windows 下查看和过滤慢请求的实际命令
phpEnv 默认日志路径在 C:\phpEnv\nginx\logs\access.log,直接双击打不开,需用命令行或工具分析:
- 用 PowerShell 快速筛选耗时超 2 秒的 PHP 请求:
Get-Content "C:\phpEnv\nginx\logs\access.log" | Select-String ' \.php " [2-5]\d\d [0-9]+ ".*[2-9]\.[0-9]{3}$'- 更准的过滤(提取最后一列 > 2.0 的行):
Get-Content "C:\phpEnv\nginx\logs\access.log" | ForEach-Object { $parts = $_ -split '\s+'; if ($parts[-1] -gt 2.0 -and $parts[-2] -ne '-') { $_ } }- 注意:Windows 下
awk不原生支持,别照搬 Linux 脚本;$upstream_response_time为空时该列为 “-”,会导致数值比较失败,必须先排除。
为什么你看到的 $upstream_response_time 总是 “-”?
这是 phpEnv 用户最常踩的坑,根本原因不是配置漏了,而是:
- PHP-FPM 未运行,或
fastcgi_pass地址/端口与 phpEnv 实际监听不一致(比如 phpEnv 默认用 socket,但配置写了127.0.0.1:9000); -
location ~ \.php$块中缺少include fastcgi_params;,导致 Nginx 无法拼出正确的 FastCGI 参数; - phpEnv 的 PHP-FPM 配置中
catch_workers_output = yes未开启,虽不影响$upstream_response_time,但会让错误不落日志,掩盖上游异常。
验证方法:临时加一行 fastcgi_param TEST_ENV "debug";,然后在 PHP 中 var_dump($_SERVER['TEST_ENV']); —— 如果拿不到,说明 FastCGI 通路根本没走通。



















