$upstream_header_time 是 nginx 记录后端首字节响应延迟的毫秒级变量,用于监控 ttfb、实现动态限流与健康检查,需注意重试覆盖、非纯应用耗时及 https 下含 tls 开销。

$upstream_header_time 是 Nginx 的一个内置变量,记录从向后端(upstream)发起请求开始,到接收到后端响应的首字节(即 HTTP 响应头结束)所经过的时间(单位:秒,精度为毫秒,格式如 0.123)。它不包含 Nginx 自身处理请求/响应头的时间,也不含网络传输响应体的时间,因此非常适合用于监控后端服务的“首包延迟”(TTFB — Time To First Byte),反映后端真实处理效率。
在 access_log 中记录并聚合分析
将该变量写入访问日志,是落地监控最常用、最轻量的方式:
- 在
http或location块中定义自定义日志格式,例如:
'$status $body_bytes_sent "$http_referer" "$http_user_agent" '
'"$upstream_addr" $upstream_header_time $upstream_response_time';
- 在 server 或 location 中启用该格式:
access_log /var/log/nginx/access.log upstream_time; - 日志中每行末尾会出现类似
10.0.1.5:8000 0.042 0.047的字段,其中0.042即$upstream_header_time(单位秒) - 后续可用 logrotate + 脚本(如 awk/Python)或 ELK、Loki + Grafana 按分钟/小时统计平均值、P95、最大值等指标
通过 stub_status 或第三方模块暴露实时指标
Nginx 原生 stub_status 不支持直接输出 $upstream_header_time,但可通过以下方式实现近实时观测:
- 使用 lua-nginx-module 在
log_by_lua_block中采集并上报:
local header_time = tonumber(ngx.var.upstream_header_time) or 0
if header_time > 0 then
-- 上报到 Prometheus Pushgateway 或本地计数器(需配合 lua-resty-prometheus)
prometheus:observe("upstream_header_time_seconds", header_time)
end
}
- 搭配 Prometheus + Grafana,即可绘制
rate(upstream_header_time_seconds_sum[5m]) / rate(upstream_header_time_seconds_count[5m])得到滑动窗口平均延迟 - 注意:该变量在失败请求(如超时、连接拒绝)中可能为空或为
-,需做空值过滤
结合 map 和 limit_req 实现动态限流策略
利用首字节延迟作为健康信号,辅助决策是否降级或限流:
- 用
map将高延迟映射为标记,例如:
default 0;
~^[0-9]\.[5-9][0-9]{2,}$ 1; # 匹配 ≥ 0.5s 的值(正则需根据精度调整)
~^[1-9][0-9]*\.[0-9]+$ 1;
}
- 再配合
limit_req对慢后端来源请求做更严格限制: -
limit_req zone=slow_limit burst=5 nodelay;(需提前定义 zone) - 也可结合
error_page 504 = @fallback,当$upstream_header_time异常长(如接近 proxy_read_timeout)时主动跳转备用上游
注意事项与常见误区
该变量看似简单,但实际使用中易被误读:
-
$upstream_header_time是每个 upstream 请求独立记录的;若配置了多个 upstream server(如轮询),且请求被重试(proxy_next_upstream),则只记录最终成功那次的值,重试过程中的延迟不会叠加或保留 - 它不等于后端应用内部耗时——中间可能包含 upstream 网络 RTT、负载均衡器转发延迟、后端 TCP 队列排队等,需结合后端自身打点交叉验证
- 时间精度依赖系统时钟和 Nginx 编译选项(需启用
--with-http_realip_module等不影响,但高精度需确保无严重时钟漂移) - 在 HTTPS backends 场景下,该时间包含 TLS 握手开销(如果 Nginx 与后端走 HTTPS),并非纯应用层处理时间











