$request_time 是 Nginx 唯一覆盖“客户端首字节到达→响应末字节发出”全过程的耗时指标,含网络接收、Nginx 处理、上游响应、响应发送四阶段,需结合 $upstream_response_time 等变量差值分析、按业务维度分层聚合,并绑定 $request_id 实现端到端可观测性。

$request_time 是 Nginx 日志中唯一能完整覆盖“客户端首字节到达 → 响应末字节发出”全过程的耗时指标,单位为秒(毫秒精度),它天然包含网络接收、Nginx 处理、上游响应、响应发送四大阶段。要真正用它做全量审计,关键不是看单个数值,而是构建可归因、可拆解、可对比的分析链路。
抓取真实、无干扰的 $request_time 数据
确保日志格式中明确记录 $request_time,并启用毫秒级时间戳(如 $msec 或 $time_iso8601)对齐时序。避免使用 proxy_buffering off 等导致响应体延迟发送的配置——否则 $request_time 会虚高,掩盖真实瓶颈。同时确认未开启 gzip on + large response body 的组合,这类场景下压缩耗时会显著拉长 $request_time,但不属于业务逻辑延迟。
用差值法定位性能损耗主责环节
单看 $request_time 容易误判。必须结合其他变量做减法:
- 若 $request_time − $upstream_response_time > 300ms:说明瓶颈在 Nginx 自身或客户端侧——比如大文件上传慢(查 $request_length)、模板渲染耗时(如使用 SSI 或 Lua)、或 SSL 握手/重协商频繁(查 $ssl_protocol、$ssl_cipher)
- 若 $upstream_response_time 接近 $request_time(差值<50ms):问题基本锁定在后端服务,此时应立即切到 $upstream_response_time 分布和 $upstream_status 联合分析
- 若 $request_time 很大但 $upstream_response_time 为 “-” 或接近 0:说明请求根本没发出去,属于连接建立失败(DNS 解析超时、TCP SYN 丢包、$upstream_connect_time 异常),需排查网络层或 upstream 配置
按业务维度分层聚合,识别隐性损耗
全量不等于堆数据,而是分层归因:
- 按 $request_method + $uri 组合统计 P95 $request_time:能快速发现某类接口(如 POST /api/v1/upload)整体偏慢,再进一步查 $request_length 是否异常增大
- 按 $status 分组观察:HTTP 200 请求平均 $request_time 是 120ms,但 499(客户端断连)请求的 $request_time 中位数是 8.2s——说明大量用户在等待时主动放弃,本质是后端响应太慢引发雪球效应
- 按 $http_user_agent 或 $http_referer 切片:发现移动端 $request_time 比桌面端高 40%,且集中在弱网模拟 UA(如 “Chrome/120.0.0.0 Mobile”),提示需优化首屏资源加载策略或启用 Brotli 压缩
关联唯一标识,打通端到端可观测性
$request_time 只是起点,不是终点。必须绑定 $request_id(全局唯一)与下游 trace_id(如 OpenTelemetry 的 trace-id),才能把 Nginx 层耗时和应用层 APM 数据对齐。例如:某次请求 $request_time = 1.83s,$request_id = abc123,通过该 ID 在 Jaeger 中查到对应 span 显示 DB 查询耗时 1.72s ——直接确认瓶颈在 SQL,而非网络或 Nginx。
不复杂但容易忽略



















