nginx响应时间测量需分场景选用变量:$request_time反映全链路耗时(含上传、处理、传输等),$upstream_response_time定位后端瓶颈(仅proxy/fastcgi场景),静态资源则依赖$request_time与缓存头分析。

Nginx 测量响应时间不是只记一个数字,而是要分场景、选对变量、配好日志、再结合上下文分析。关键在于明确“你在测什么”——是用户端整体耗时?还是后端真实处理慢?抑或是静态文件读取卡顿?不同目标对应不同变量和诊断路径。
用 $request_time 看整条链路耗时
这是最常用也最容易误解的变量。它从收到客户端第一个字节开始计时,到发出最后一个响应字节结束,单位是秒(精度毫秒,如 0.047 表示 47ms)。它包含:
- 客户端上传时间(尤其大 Body 时不可忽略)
- Nginx 内部排队、解析、重写等开销
- upstream 等待与响应传输时间
- TLS 握手、gzip 压缩等额外开销
配置示例:
log_format main '$remote_addr - [$time_local] "$request" $status $body_bytes_sent $request_time $msec'; access_log /var/log/nginx/access.log main;
注意:$msec 提供日志写入时刻的毫秒级时间戳,方便对齐其他系统日志;不要用 $time_local 做耗时计算,它只精确到秒。
用 $upstream_response_time 定位后端瓶颈
仅在 proxy_pass 或 fastcgi_pass 场景下有效,表示 Nginx 向后端发起请求到收到响应头的时间(不含上传和响应体发送)。它能帮你快速判断:
- 值为
-:根本没发请求(如 404、rewrite 跳转、proxy_pass 未命中) - 多值逗号分隔(如
0.002,0.003,1.289):启用了重试,最后一段突增说明某次重试出问题 - 明显小于
$request_time:瓶颈在 Nginx 层或客户端网络 - 接近
$request_time:后端大概率是根因
必须搭配 $upstream_addr 和 $upstream_status 才有意义:
log_format perf '$remote_addr $upstream_addr $upstream_response_time $upstream_status $request_time $uri $request_id';
区分静态资源与动态代理的监控策略
静态文件不走 upstream,$upstream_response_time 恒为 -,此时必须依赖 $request_time,并聚焦 Nginx 本机行为:
- 用
location精确匹配.js,.css,/static/等路径,启用专用日志 - 加
add_header X-File-Cache $upstream_cache_status(proxy_cache)或X-Static-Hit $sent_http_content_length(直接服务)辅助判断缓存效果 - 配合
open_file_cache使用,避免反复打开文件带来的 I/O 波动
用外部工具做有效统计,别信平均值
Nginx 不计算平均值,也不提供分位数。原始日志需导入可观测系统:
- Prometheus + nginx-prometheus-exporter:开启
--enable-upstream-stats或--enable-static-stats,用histogram_quantile(0.95, ...)查 P95,比平均值更能反映长尾问题 - Loki + Grafana:用 LogQL 提取
$request_time字段,再聚合quantile_over_time(0.90, ...) - 临时排查可用 awk:
awk '$NF > 0 && $NF != "-" {sum += $NF; cnt++} END {print "P95 approx:", asorti(a=a, a, "numeric")}'(配合排序脚本更准)
验证配置是否生效的三步检查法
-
nginx -t && nginx -s reload后,用curl -I http://your.site/api/test触发一次请求 - 查看日志末尾字段:是否出现类似
10.1.2.3:8080 0.042 200 0.051的组合(upstream_addr+upstream_response_time+upstream_status+request_time) - 对比异常请求:若某次
$upstream_response_time是 1.2s 但$request_time是 1.21s,说明后端慢;若$request_time是 3.5s 而$upstream_response_time只有 0.04s,问题可能在客户端上传或 Nginx gzip 压缩阶段
不复杂但容易忽略











