Nginx反向代理中可通过配置log_format记录各阶段耗时,关键变量包括$request_time、$upstream_connect_time、$upstream_header_time和$upstream_response_time,需在启用proxy_pass的location中生效,并支持重试场景下的多值分隔与瓶颈定位分析。

要在 Nginx 反向代理中清晰记录各阶段耗时,关键不是开启某个开关,而是正确配置日志格式并理解每个内置时间变量的含义和生效条件。只要 proxy_pass 生效且后端返回响应,Nginx 就能天然提供多段细分耗时,无需额外模块。
记录核心耗时字段的日志格式
在 http 块中定义一个包含代理时间变量的日志格式:
log_format proxy_timing '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent ' 'rt=$request_time uct="$upstream_connect_time" uht="$upstream_header_time" urt="$upstream_response_time" ' 'upstream=$upstream_addr status=$upstream_status';其中各变量含义明确:
- $request_time:整条链路总耗时(秒,毫秒精度),从收到客户端首字节到发完响应末字节
- $upstream_connect_time:Nginx 与后端建立 TCP 连接所用时间(含 DNS、TLS 握手)
- $upstream_header_time:从连接建立完成到收到后端响应首行(含状态码)的时间
- $upstream_response_time:从发起请求到接收完全部后端响应数据的时间(header + body)
确保变量在代理位置生效
这些变量只在启用 proxy_pass 的 location 中有效,且后端必须返回响应(否则显示为“-”)。示例配置:
proxy_pass http://backend_cluster;
proxy_set_header Host $host;
access_log /var/log/nginx/api_timing.log proxy_timing;
}
注意:$upstream_response_time 和 $upstream_status 都支持重试场景——若发生多次 upstream 调用(如启用 proxy_next_upstream),它们会以逗号分隔,例如 0.012, 0.045 和 502, 200,可据此匹配最终成功的一次。
区分瓶颈发生在哪一环
单看一个数值意义有限,需横向对比判断问题根源:
- 若 $request_time ≫ $upstream_response_time:瓶颈可能在客户端网络、Nginx 自身处理(如大文件上传、SSL 开销)或响应发送阶段
- 若 $upstream_connect_time 明显偏高:关注 DNS 解析慢、后端地址不可达、TLS 协商延迟或连接池不足
- 若 $upstream_header_time ≈ $upstream_response_time:说明后端响应体极小,耗时集中在业务逻辑或数据库查询
- 若 $upstream_header_time 大但 $upstream_response_time 更大:后端可能流式输出或响应体庞大
透传耗时给前端用于监控
前端埋点或网关降级策略常需实时获取后端处理耗时,可通过响应头透出:
location /api {proxy_pass http://backend;
add_header X-Upstream-Time $upstream_response_time;
add_header X-Request-Time $request_time;
}
注意:proxy_hide_header 通常不需要,除非后端也设置了同名头需屏蔽;该头值在后端返回 200/5xx 等任何 HTTP 响应时均有效,但若请求未到达 upstream(如被限流或路由失败),则为空。


















