要确认 proxy_cache_revalidate 是否真正节省回源带宽,核心是日志中识别 $upstream_cache_status=REVALIDATED 且 $upstream_http_content_length≤500,表明成功复用旧缓存仅传响应头;需配合自定义日志、curl 验证及源站 bytes_sent 对比,排除误返 200 或解析异常等陷阱。

要确认 proxy_cache_revalidate 是否真正节省了回源带宽,核心是捕获并分析 Nginx 日志中出现的 REVALIDATED 状态——它明确表示:缓存已过期,Nginx 发起了条件请求(If-Modified-Since 或 If-None-Match),且源站返回了 304 Not Modified,成功复用本地缓存体,仅传输响应头。
在日志中精准识别 REVALIDATED 行为
需先启用带缓存状态的自定义日志格式,并确保记录关键变量:
- 在
http块中定义日志格式:log_format cache_log '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $upstream_cache_status $upstream_http_content_length $upstream_response_time'; - 在对应 location 或 server 块中启用:
access_log /var/log/nginx/revalidate.log cache_log; -
$upstream_cache_status是唯一能直接反映 revalidate 结果的变量;只有值为 REVALIDATED 才代表条件验证成功 - 配合
$upstream_http_content_length可判断实际回源响应大小:若该值 ≤ 500,基本可认定是干净的 304(仅含头部);若 > 10 KB,则说明源站误返回了完整 200,revalidate 失效
通过响应头快速人工验证
用 curl -I 模拟客户端请求,观察是否触发 revalidate 流程:
- 首次访问(缓存未命中):
应看到X-Cache: MISS、Last-Modified或ETag头存在,且Content-Length明显较大 - 等待缓存过期(如
proxy_cache_valid 200 10m后)再访问:
若返回HTTP/1.1 304 Not Modified,且无Content-Length或值极小(如 0),同时X-Cache: REVALIDATED,即为成功路径 - 注意:浏览器强制刷新(F5)可能携带
Cache-Control: max-age=0,默认会绕过缓存直连后端——需配合proxy_cache_bypass $http_cache_control;控制逻辑
对比带宽节省效果的关键指标
不能只看状态码,要关联真实流量数据:
- 统计单位时间内日志中
REVALIDATED出现次数占所有回源请求(MISS+EXPIRED+REVALIDATED)的比例。75%+ 的REVALIDATED率,通常对应约 60–80% 的响应体带宽下降 - 比对开启前后源站 access log 的
bytes_sent总和:若 revalidate 生效,该值应显著降低,而requests数可能微增(因每次过期都需一次验证请求) - 检查
$upstream_cache_last_modified变量(仅在REVALIDATED时有值):它记录的是 Nginx 本次“保鲜”所依据的源站时间戳,与$upstream_http_last_modified一致,说明源站时间语义准确
排除常见误判陷阱
以下情况看似有 REVALIDATED,但并未节省带宽:
- 源站返回
304却附带Content-Length: 0或空响应体 → Nginx 可能解析失败,降级为重新下载,日志仍记为REVALIDATED,但实际传输了完整 body - 后端返回
Cache-Control: no-cache或private→ Nginx 根本不缓存,REVALIDATED不会出现,所有请求都是MISS - 未启用
proxy_cache_lock→ 多个并发请求同时触发 revalidate,造成多路 304 请求,虽单次省带宽,但总回源请求数激增,反而加重源站压力










