要让 proxy_cache_revalidate 节省约 80% 带宽,关键在于源站必须正确响应 If-Modified-Since 并返回 304;若源站误返 200,则优化归零,且需配合 proxy_cache_lock、background_update 等指令协同生效。

要让 proxy_cache_revalidate 真正节省约 80% 的带宽,关键不在 Nginx 单方面配置,而在于它与上游源站的条件请求机制形成闭环——尤其是源站必须正确响应 If-Modified-Since 并返回 304 Not Modified。实测中,对静态资源或低频更新接口,命中 304 的比例达 75%–90%,带宽下降自然接近这个区间。
确保源站支持并正确返回 304
这是整个机制生效的前提。Nginx 发出带 If-Modified-Since 的验证请求后,如果源站直接返回 200(哪怕内容没变),Nginx 就会覆盖缓存、传输完整响应体,带宽优化归零。
- 静态文件(如 .js/.css/.png):只要源站是标准 Web 服务器(Nginx/Apache),且未禁用
Last-Modified头,通常默认支持 304 - 动态接口(如 PHP/Node.js):需手动检查请求头中的
If-Modified-Since,比对资源最后修改时间,若未变更则显式输出HTTP/1.1 304 Not Modified,且不输出响应体 - 避免常见错误:源站返回 304 时仍带
Content-Length: 0或空响应体,可能触发 Nginx 解析异常;应确保响应干净,仅含状态行和必要头(如Date)
合理设置缓存生命周期与 revalidate 触发时机
proxy_cache_revalidate 只在缓存“过期但尚未被清除”时才启用。如果缓存有效期太短(如 proxy_cache_valid 200 1s),会导致高频回源验证;太长则失去及时性。需要平衡新鲜度与复用率。
- 对 CSS/JS 等不变资源:设长缓存(
proxy_cache_valid 200 1y),基本不走 revalidate,靠 URL 哈希更新 - 对 HTML、API 列表页等轻量可变内容:设中等有效期(如
proxy_cache_valid 200 10m),让 revalidate 在过期后自动介入 - 配合
inactive=1h(在proxy_cache_path中),保证即使长期无访问,缓存条目也不会无限滞留
Nginx 缓存层必须开启关键配套指令
单独打开 proxy_cache_revalidate on 不够。它依赖其他指令协同工作,否则可能降级为普通回源或并发击穿。
-
proxy_cache_lock on:防止同一缓存 key 的多个并发请求同时触发上游验证,只让第一个去问,其余等待并复用结果 -
proxy_cache_lock_timeout 200ms:避免锁等待过久,超时后允许另一个请求发起验证 -
proxy_cache_background_update on:当缓存过期且有请求命中时,立即返回旧缓存 + 异步后台刷新,既保体验又保新鲜度 - 确认
proxy_cache_use_stale updating已启用:万一后台更新失败,仍可用过期缓存兜底,避免雪崩
验证是否真实节省带宽
不能只看 Nginx 日志里有没有 “304”。要从三个层面交叉确认:
- 浏览器 Network 面板:查看重复请求是否返回 304,响应体大小是否为 0
- Nginx access log:添加
$upstream_http_content_length和$upstream_status字段,统计 304 请求占比及对应 upstream 响应体大小 - 源站监控:确认上游收到的请求中,带
If-Modified-Since的比例,以及其中返回 304 的比例;若源站 304 率低于 70%,说明源站逻辑或资源更新频率需调整


















