核心是正确使用$upstream_response_time变量,它仅在proxy_pass等代理请求成功进入upstream时生效,静态资源、rewrite拦截等场景显示为-;需在http块定义含$request_time、$upstream_response_time、$upstream_addr、$upstream_status的自定义log_format,并在proxy location中启用access_log,才能准确记录后端真实响应耗时。

要在 Nginx 日志中记录后端真实响应耗时,核心是正确使用 $upstream_response_time 变量,并确保它有值可写——这个变量只在请求真正转发给 upstream(如通过 proxy_pass)时才生效,静态服务、rewrite 拦截或错误页处理等场景下会显示为 -。
定义含 upstream 响应时间的日志格式
必须在 http{} 块中定义自定义日志格式,不能放在 server 或 location 里。推荐包含关键对比字段:
-
$request_time:整个请求生命周期耗时(从收到首字节到发完响应),单位秒,毫秒精度 -
$upstream_response_time:Nginx 与后端交互耗时(发送请求→收完响应体),仅代理有效 -
$upstream_addr:实际通信的后端地址,便于定位慢节点 -
$upstream_status:后端返回的状态码,区分是慢还是错
示例配置:
确保 upstream 响应时间能被采集
该变量不是“开箱即用”,需满足三个前提:
- 必须使用
proxy_pass(或fastcgi_pass等 upstream 类指令),且请求实际进入 upstream 流程 - 建议显式定义 named upstream 块,而非直写 IP:
upstream backend { server 127.0.0.1:8000; }
对应 location 中写proxy_pass http://backend;,更稳定兼容 - Nginx 1.9.1+ 默认启用 upstream 计时,无需额外开启;旧版本需确认是否支持
在 location 中启用该日志格式
仅定义格式还不够,需在实际处理代理请求的 location 块中指定 access_log:
- 不要在顶层 server 或全局 http 块中直接启用,避免非代理请求也尝试记录(此时
$upstream_response_time为空) - 推荐在具体 proxy location 中启用,例如:
proxy_pass http://backend;
access_log /var/log/nginx/api_upstream.log upstream_log;
}
解读日志中的响应时间字段
日志行末尾类似这样的内容:
0.125 0.121 "127.0.0.1:8000" 200
-
0.125是$request_time,总耗时 125ms -
0.121是$upstream_response_time,后端响应占 121ms - 差值约 4ms,可能是 Nginx 处理 header、缓冲或网络发送开销
- 若出现
"0.002, 0.045",说明发生重试;配合$upstream_status "200, 504"可判断是否首次失败后重试成功











