通过$upstream_response_time有无及大小可快速定位缓存失效或后端慢:有值即回源,无值(“-”)即命中缓存;若大量慢请求该值为“-”,问题在缓存策略;若普遍有值且>500ms且$cache_status为miss,则源站响应慢。

直接看 $upstream_response_time 的有无和大小,就能快速区分是缓存没起作用,还是后端真慢了。它不依赖客户端、不掺杂网络抖动,只反映“Nginx 到后端”这一跳是否健康。
看值是否存在:有值 = 回源,无值(或为“-”)= 未回源
CDN 或 Nginx 网关在命中缓存时,根本不会发请求给后端——此时日志中 $upstream_response_time 字段通常为空、为“-”,或压根不记录(取决于 log_format 配置)。只要这个字段出现具体数值(如 0.023、1.487),就说明该请求一定回源了。
- 如果大量慢请求的 $upstream_response_time 是“-”,但用户端延迟高 → 缓存策略可能生效了,问题出在缓存内容陈旧、缓存未覆盖关键路径,或客户端本地缓存/CDN 节点缓存失效
- 如果慢请求里 $upstream_response_time 普遍有值(尤其 >500ms),且 $cache_status 是 MISS → 明确是源站响应慢,不是缓存的问题
看值的大小分布:集中高延时 = 后端瓶颈,随机毛刺 = 局部异常
对所有带数值的 $upstream_response_time 做直方图统计,重点关注右尾(>200ms、>1s 区间):
- 若 95% 的值都
- 若高延迟请求与特定 $upstream_addr 高度重合(例如 10.0.5.22:8080 占比超 80%)→ 单台后端实例异常,不是整体架构或缓存策略问题
- 若高延迟请求同时伴随大量 $upstream_status = 504,且数值接近你配置的 proxy_read_timeout(如 3s)→ 后端已超时未响应,需查其 GC、DB 锁、线程池耗尽等
结合 cache_status 和 request_uri 交叉验证
单看时间不够,必须绑定上下文才能归因:
- cache_status = HIT 但用户反馈页面错乱或过期 → 不是性能问题,是缓存策略配错(比如把带用户态的 /api/user/info 缓存了)
- cache_status = MISS 且 $request_uri 是静态资源(如 /static/logo.png)→ 缓存规则漏配或参数未忽略(如 ?v=1.2.3 未启用 ignore_args)
- cache_status = BYPASS(某些 CDN 支持)+ $upstream_response_time 高 → 可能命中了强制绕过缓存的 header(如 Cache-Control: no-cache),需检查业务代码或中间件是否误加
一个实操判断流程
拿到一批慢请求日志后,按顺序执行三步筛选:
- 第一步:提取所有 $upstream_response_time != "-" 且 > 0.8 的行 → 锁定真实回源慢请求
- 第二步:对这批数据按 $request_uri 分组,统计平均 $upstream_response_time → 找出最拖后腿的接口
- 第三步:在该接口下,再按 $upstream_addr 分组,看是否某台机器显著偏高 → 决定是优化代码,还是摘除故障节点
这样几条命令下来,不用翻后端日志,就能确认问题到底出在缓存配置疏漏,还是后端服务本身。











