监控 Nginx 响应时间需分清“谁耗的时、在哪耗的时、怎么量才准”,核心是结合 $request_time、$upstream_response_time、$upstream_connect_time 等变量精准归因,按路径分离日志,并用 Prometheus+Grafana 或 ngxtop 落地可观测。

监控 Nginx 请求响应时间,关键不是堆工具,而是分清“谁耗的时、在哪耗的时、怎么量才准”。静态资源、代理后端、TLS握手、客户端网络——每类延迟来源不同,变量和工具必须对齐。
用对变量:$request_time 是主干,但不能单靠它
$request_time(单位秒,毫秒精度)是从收到请求首字节到发出响应末字节的全程耗时,覆盖网络、Nginx 处理、文件读取或 upstream 等全部环节。它适合做整体水位判断,比如 P95 是否突破 200ms。
但单看它容易误判。需同步记录:
- $upstream_response_time:仅在 proxy_pass/fastcgi_pass 场景下有效,反映后端真实处理耗时(不含上传与发送),用于定位是 Nginx 自身慢还是后端拖累;
- $upstream_connect_time:排查 DNS 解析、TCP 建连、TLS 握手等前置延迟;
- $msec:提供日志写入的精确时间戳(秒+毫秒),便于与后端或链路追踪日志对齐;
- $status 和 $sent_http_cache_control:结合状态码和缓存头,区分是 499(客户端断连)、504(超时)还是 200 缓存命中。
日志分离:按路径/用途打标,避免混流干扰
所有请求共用一条 access_log,等于把 CDN 缓存、静态文件、API 接口全搅在一起分析,结果失真。应通过 location 精准分流:
- 静态资源(如
location ~* \.(js|css|png|jpg)$):启用独立日志格式,记录$request_time $msec,并加响应头X-Static-Hit $sent_http_content_length辅助判断是否命中 open_file_cache; - 代理接口(如
location /api/):单独 log_format,必含$upstream_response_time $upstream_addr,支持按节点或算法(round-robin / least_conn)做横向对比; - TLS 相关路径(如
location /healthz或带证书验证的 endpoint):额外记录$ssl_protocol $ssl_cipher,排查 OCSP Stapling 或密钥交换导致的握手延迟。
可观测落地:Prometheus + Grafana 是当前最稳路径
Nginx 不算中位数、不聚合分位数,这些必须交给下游系统。推荐组合:
- 采集层:用
nginx-prometheus-exporter,开启--enable-static-stats(静态资源)或--enable-upstream-stats(后端接口),暴露直方图指标如nginx_static_request_seconds_bucket; - 查询层:Grafana 中用
histogram_quantile(0.95, sum(rate(nginx_static_request_seconds_bucket[5m])) by (le))查 P95,用stddev_over_time() / avg_over_time()算抖动比,持续 >0.3 表示延迟不稳定; - 归因层:叠加
upstream_cache_status或lb_strategy标签,确认高延迟是否集中在 MISS、重试或某类负载算法上。
轻量替代方案:ngxtop 适合快速现场诊断
没有 Prometheus?ngxtop 可直接解析实时日志流,无需部署额外服务:
- 查慢请求:
ngxtop --filter "request_time > 1"(响应超 1 秒的请求); - 按路径排序:
ngxtop top request_path --order-by request_time找出平均最慢的接口; - 分析历史日志:
ngxtop --no-follow --access-log /var/log/nginx/access.log回溯故障时段; - 自定义聚合:
ngxtop query "select status, count(1), avg(request_time) from stdin group by status"快速看各状态码耗时分布。


















