“proxy_cache_revalidate”不是 Nginx 的合法配置指令,属长期误传的伪指令;真正起作用的是后端响应中的 ETag 或 Last-Modified 头,配合 Nginx 内置协商逻辑——缓存过期时自动发起 If-None-Match 或 If-Modified-Since 条件请求,收到 304 后复用旧缓存体,从而节省带宽。

“proxy_cache_revalidate”不是 Nginx 的合法配置指令——它在所有官方文档、源码和稳定版本中都不存在。你在网上看到的这类配置,是长期误传的“伪指令”,本质混淆了 HTTP 协议机制与 Nginx 实际行为。
真正起作用的是标准 HTTP 缓存头和 Nginx 内置协商逻辑
Nginx 本身不依赖任何叫 proxy_cache_revalidate 的开关,而是自动根据后端响应中的以下字段,在缓存过期时发起条件请求:
-
ETag:存在时,Nginx 自动添加
If-None-Match头回源校验 -
Last-Modified:存在时,Nginx 自动添加
If-Modified-Since头 - 两者共存时,优先使用
If-None-Match(更精确) - 只有后端返回
304 Not Modified,Nginx 才复用旧缓存、不传响应体,从而减少带宽
要让 ETag 发挥作用,后端必须正确生成和响应
再强的 Nginx 配置也救不了不配合的后端。关键点如下:
- ETag 值需带英文双引号,如
ETag: "a1b2c3"(弱标签为W/"a1b2c3") - ETag 必须随内容变化而变化,推荐用内容哈希(如 MD5/SHA256),禁用固定值或时间戳
- 收到
If-None-Match请求头后,后端必须严格比对并返回304,且响应体为空、不设Content-Length: 0 - 静态资源(.js/.css/.png)由 Nginx/Apache 直接托管时通常默认支持;动态接口需自行实现校验逻辑
Nginx 端需配置合理缓存策略与保护机制
确保缓存能被有效复用,而不是频繁失效或并发击穿:
- 用
proxy_cache_valid 200 302 1h;设置明确缓存时长(别只靠Expires) - 开启
proxy_cache_lock on;,防止多个请求同时触发回源验证 - 搭配
proxy_cache_use_stale updating;,让用户始终拿到旧缓存,后台异步刷新 - 可选启用
proxy_cache_background_update on;,提升响应连续性 - 缓存路径中设置
inactive=1h;,及时清理冷数据释放空间
如何验证 ETag 协商是否真实生效
不能只看配置,得看实际行为:
- 在
log_format中加入$upstream_cache_status,例如:log_format main '$remote_addr - $upstream_cache_status "$request" $status'; - 访问日志中出现
revalidated表示成功发起条件请求并收到 304 - 用
curl -I观察响应头:首次访问应有ETag和Cache-Control;过期后再次访问若返回304且无Content-Length,说明生效 - 对比开启前后后端 access log 的响应字节数,典型节省幅度在 40%–80%,取决于资源更新频率











