Nginx 中如何通过 $upstream_header_time 计算处理耗时

作者:袖梨 2026-08-08

$upstream_header_time 是 Nginx 表示从发起上游请求到接收响应状态行耗时的毫秒级变量,仅含网络传输与后端首字节生成时间,用于分析 TTFB 和定位后端瓶颈,日志中需过滤“-”并注意多 upstream 场景。

$upstream_header_time 是 Nginx 内置变量,表示从 Nginx 向上游服务器(如后端应用)发起请求开始,到接收到上游响应首行(即状态行,例如 HTTP/1.1 200 OK)所经过的时间,单位为秒,精度为毫秒(格式如 0.0020.125)。

它反映的是“后端响应头到达时间”,不是完整请求耗时

注意:$upstream_header_time 不包含 Nginx 接收完整响应体(body)的时间,也不含 Nginx 自身处理逻辑(如 rewrite、access 日志写入等)的开销。它仅衡量“Nginx 发起请求 → 收到后端 HTTP 状态行”的网络+后端首字节生成耗时。

常见用途是评估后端服务的首字节延迟(TTFB),用于判断后端是否慢、是否存在连接/排队瓶颈。

如何在日志中记录并用于分析

log_format 中加入该变量即可记录:

log_format main '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' '$upstream_header_time $request_time $upstream_response_time';

其中:

  1. $upstream_header_time:后端返回响应头耗时(关键 TTFB 指标)
  2. $upstream_response_time:后端返回完整响应耗时(含 body 传输)
  3. $request_time:整个请求从读取首字节到日志写入的总耗时(Nginx 全链路)

结合其他变量估算各阶段耗时

虽然无法直接拆解出“Nginx 处理时间”或“网络传输时间”,但可通过差值辅助定位瓶颈:

  1. $upstream_header_time ≈ $upstream_response_time,说明后端响应体很小或已快速生成,瓶颈大概率在后端逻辑(而非网络或大文件传输)
  2. $upstream_response_time ≫ $upstream_header_time,说明后端返回了 header 却迟迟发不完 body,可能是流式输出慢、大文件传输、或后端边生成边发(如 chunked)
  3. $request_time − $upstream_response_time 显著大于 0(比如 >10ms),可能涉及 Nginx 本身操作:日志写入阻塞、proxy_buffer 不足导致等待、gzip 压缩耗时、或者大量 if/rewrite 规则执行

使用注意事项

该变量仅在成功转发到 upstream 且收到响应时有值;若发生超时、502、504 或 upstream 不可用,其值为空或为“-”。因此做统计分析时需过滤掉“-”:

# 用 awk 统计平均 header_time(跳过 '-' 行)awk '$12 != "-" {sum += $12; cnt++} END {print "avg:", sum/cnt}' access.log

另外,多个 upstream(如负载均衡多台机器)会以逗号分隔多个值(如 0.012, 0.009, 0.015),此时需按实际需求取第一个、平均值或最大值——默认日志中只记第一个 upstream 的值,除非显式配置 log_format 使用 $upstream_header_time 的数组形式(需较新 Nginx 版本支持)。

相关文章

精彩推荐