要让nginx access_log有效排查慢接口,需启用并记录$upstream_connect_time、$upstream_header_time、$upstream_response_time三个变量,它们分别反映后端建连、首包、全响应耗时,且仅在proxy_pass等代理场景下有效;必须在log_format中定义并显式在access_log指令中引用该格式名,否则新字段不生效。

要让 Nginx 的 access_log 真正帮上忙排查慢接口,关键不是只记个总时间,而是把后端服务的真实响应耗时单独、准确地剥离出来。$request_time 看起来方便,但它混入了客户端网络、Nginx 自身处理等干扰项;真正反映后端快慢的,是 $upstream_response_time 和更精细的 $upstream_header_time。
必须启用 upstream 相关变量并写入日志格式
这些变量只在用了 proxy_pass(或 FastCGI/GRPC 等代理指令)的 location 中有效。直接在 http 块里定义日志格式,并确保该格式被显式引用:
log_format upstream_lat '[$time_local] $remote_addr "$request" '
'$status $body_bytes_sent '
'rt=$request_time '
'uct="$upstream_connect_time" '
'uht="$upstream_header_time" '
'urt="$upstream_response_time" '
'upstream="$upstream_addr"';
然后在对应 server 或 location 块中启用:
access_log /var/log/nginx/backend-latency.log upstream_lat;
注意:不能只改 log_format 就完事,access_log 指令必须明确写上你自定义的格式名(如 upstream_lat),否则仍走默认 combined,新字段不会出现。
重点看这三个 upstream 时间字段
-
$upstream_connect_time:Nginx 与后端建立 TCP 连接花了多久。如果它明显偏高(比如 >500ms),问题可能出在后端监听配置、连接池耗尽、或中间网络延迟。 -
$upstream_header_time:从发请求到收到第一个响应头的时间。这是后端“开始处理并返回结果”的真实信号,最适合作为延迟基线(例如 P95 > 800ms 就告警)。 -
$upstream_response_time:整个响应体接收完成的时间。若它比uht大很多,说明后端是流式输出或大文件传输慢,而非逻辑卡顿。
快速定位慢请求的实用方法
- 查单次慢请求:用
grep "urt=\"[2-9]\.[0-9]\+\"" /var/log/nginx/backend-latency.log找响应超 2 秒的记录。 - 统计某接口平均耗时:
awk '$12 ~ /\"[0-9]+\.[0-9]+\"/ {split($12,a,"\""); sum+=a[2]; cnt++} END {print "avg:", sum/cnt}' /var/log/nginx/backend-latency.log(假设urt是第 12 字段)。 - 对比
uht和urt差值大的请求,再结合upstream_addr看是否集中在某个后端实例,可快速锁定具体服务节点。
不复杂但容易忽略











