$upstream_response_time仅记录nginx发完请求到收首字节的时间,不含dns、tcp建连、ssl握手及响应体传输;需配合log_format、upstream优化与多变量协同分析才准确反映后端业务耗时。

要在 Nginx 日志中准确记录 upstream 响应时间,关键不是简单加一个变量,而是理解 $upstream_response_time 的行为边界,并配合日志格式、上游配置和业务逻辑协同使用,才能让它真正反映后端服务的业务处理耗时。
明确 $upstream_response_time 的真实含义
该变量只在使用 proxy_pass、fastcgi_pass 等反向代理指令且后端成功返回响应头时生效。它记录的是 Nginx 发送完请求(包括 request body)到接收到第一个响应字节(即 response header 开始到达)之间的时间,单位为秒,精度达毫秒(如 0.042 表示 42ms)。
它不包含以下环节:
- DNS 解析、TCP 连接建立(除非复用连接)、SSL/TLS 握手
- 客户端上传请求体的时间
- Nginx 向客户端发送响应体的时间
- 后端生成响应体的耗时(如流式导出大文件)
因此,它最贴近“后端应用逻辑处理 + 网络往返”,但前提是后端尽快输出 header。
正确配置 log_format 并启用日志记录
在 http 块中定义日志格式,确保包含 $upstream_response_time,且不加引号包裹该变量:
log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_time $upstream_response_time $upstream_addr $upstream_status';
然后在 server 或 location 块中启用:
access_log /var/log/nginx/access.log main;
注意:
- 若请求未进入 upstream(如静态文件、rewrite 拦截、404、限流拦截),该值显示为
- - 多台 upstream 或重试时,值以逗号分隔,如
"0.012, 0.035",对应每次尝试的耗时 - 建议同时记录
$upstream_addr和$upstream_status,便于匹配哪一次是最终成功调用
优化 upstream 配置提升指标可信度
默认配置下,$upstream_response_time 可能混入连接开销或被重试稀释。需针对性优化:
- 启用连接复用:
upstream backend { keepalive 32; },并在 location 中设置proxy_http_version 1.1;和proxy_set_header Connection ''; - 避免隐式重试:检查
proxy_next_upstream是否对 5xx 或 timeout 过度触发重试,否则日志中多个逗号值会掩盖真实慢节点 - 禁用缓冲需谨慎:设
proxy_buffering off;可让耗时延至首个响应字节到达,更贴近后端实际开始输出的时间,但会增加 worker 资源占用,仅建议调试期临时开启
结合其他变量做有效分析
单看 $upstream_response_time 只知后端花了多久,归因还需上下文:
- 对比
$request_time:若两者接近,瓶颈大概率在后端;若$request_time显著更大,问题可能在客户端网络、Nginx 排队或 SSL 解密等环节 - 引入
$upstream_connect_time:排查 TCP 建连阶段延迟(不含 DNS 和 TLS) - 添加
$request_id或自定义 header(如X-Service-Name),再通过$http_x_service_name记录服务标识,便于微服务链路追踪 - 用
$upstream_status过滤掉失败调用(如 502/504),避免超时值干扰 P95 统计











