$upstream_header_time 表示 Nginx 从发出请求到收到后端响应头首字节的时间,单位秒、精确至毫秒;需在 log_format 中显式配置并启用 access_log,用于定位后端首字节延迟根因。

直接看 $upstream_header_time 的值就能知道后端返回响应头首字节用了多久——它记录的是 Nginx 从向 upstream 发出请求,到收到第一个响应字节(即响应头的起始部分)之间的时间,单位是秒,精确到毫秒(如 0.123 表示 123ms)。
确认日志中已启用该变量
这个变量默认不会写入 access log,需主动配置。检查你的 log_format 是否包含它:
- 在
http或server块中定义日志格式,例如:log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $upstream_header_time $upstream_response_time $request_time'; - 确保
access_log使用了该格式,比如:access_log /var/log/nginx/access.log main; - 重启或重载 Nginx 生效:
nginx -s reload
区分它和其它延迟指标
$upstream_header_time 只反映“后端开始吐数据”的耗时,不是整个响应时间:
- $upstream_header_time:Nginx 发完请求 → 收到响应头第一个字节(含 TCP 握手、后端处理、网络传输等)
- $upstream_response_time:Nginx 发完请求 → 收完全部响应体(含流式响应的总耗时)
- $request_time:客户端建立连接 → Nginx 返回最后一个字节(含 Nginx 自身开销)
若 $upstream_header_time 高但 $upstream_response_time 接近它,说明后端响应快但首字节慢(可能是业务逻辑卡在初始化、数据库连接池打满、慢查询前置等);若两者差值大,说明后端是流式输出或大文件传输。
用日志做基础监控和告警
无需额外工具,靠日志 + 简单脚本就能发现异常:
- 用
awk统计 P95/P99 延迟:awk '{if($NF>0) print $NF}' /var/log/nginx/access.log | sort -n | awk 'BEGIN{c=0}{a[c++]=$1}END{print "P95:", a[int(c*0.95)]}' - 筛选超时请求(比如 >1s):
awk '$(NF-2)>1 {print $0}' /var/log/nginx/access.log(假设$upstream_header_time是倒数第三列) - 配合
tail -f实时观察:tail -f /var/log/nginx/access.log | awk '{print $(NF-2)}' | awk '$1>0.5 {print "SLOW:", $1}'
结合其他信息定位根因
单看 $upstream_header_time 只能确认“慢”,不能确定“为什么慢”。建议关联以下字段一起分析:
-
$request:看是否特定路径(如
/api/order/create)持续偏高 - $status:排除是否因 5xx 导致后端重试或兜底逻辑拖慢首字节
- $upstream_addr:确认是否某台后端实例异常(如某 IP 延迟突增)
- $http_x_real_ip 或 $remote_addr:排查是否某类客户端(如特定运营商、区域)网络质量差
如果发现规律性毛刺,再进一步查后端应用的 GC 日志、DB 慢查询、线程堆栈,就更有针对性。


















