Nginx 不支持 proxy_cache_revalidate 指令,其缓存更新依赖标准 HTTP 头(如 ETag、s-maxage)及内置协商逻辑;启用 proxy_cache 并配置合理 cache_valid、cache_use_stale 等参数后,Nginx 会自动发起条件请求实现智能更新。

proxy_cache_revalidate 并不是 Nginx 的合法配置指令——它在官方文档、源码及所有稳定版本中均不存在。这是一个长期被误传的“伪指令”,常见于过时教程或配置片段中,本质是对 HTTP 协议机制与 Nginx 缓存行为的混淆。
真正起作用的,是 Nginx 对标准缓存头(如 Cache-Control: public, s-maxage=3600)的自动遵守,以及其内置的协商缓存逻辑:当缓存过期、且后端响应中包含有效的 ETag 或 Last-Modified 时,Nginx 会自动发起带 If-None-Match 或 If-Modified-Since 的条件请求,无需任何额外开关。
所以,“利用 proxy_cache_revalidate 配合后端实现智能缓存更新”这个说法本身不成立。但你可以通过以下真实、有效、已验证的方式,达成接近目标效果的智能缓存更新:
后端必须输出可靠的校验标识
Nginx 发起条件请求的前提,是后端提供可信赖的内容指纹。重点不是“加个指令”,而是确保响应头正确:
- ✅ 响应中必须包含
ETag(推荐)或Last-Modified-
ETag应基于内容生成(如md5(file_content)),每次变更必须变化 - 格式需规范:
ETag: "abc123"(强标签)或ETag: W/"def456"(弱标签)
-
- ❌ 避免固定值(如
"static")、时间戳硬编码、或缺失引号
例如 Node.js(Express)中:
res.set('ETag', `"${crypto.createHash('md5').update(content).digest('hex')}"`);
Nginx 需启用缓存并尊重后端策略
只要后端返回了 s-maxage 或 max-age,Nginx 就会在过期后自动走协商流程:
- 设置基础缓存区:
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=static_cache:10m max_size=1g inactive=1h;
- 在 location 中启用缓存,并兜底设置有效期(覆盖无响应头的场景):
location ~* \.(js|css|png|jpg|gif)$ { proxy_pass http://backend; proxy_cache static_cache; proxy_cache_valid 200 302 1h; # 无 s-maxage 时也缓存 1 小时 proxy_cache_use_stale updating; # 过期校验中,仍返回旧内容 proxy_cache_lock on; # 防止并发回源 proxy_cache_background_update on; # 异步刷新,不影响用户 }
智能更新的关键不在“验证”,而在“控制生命周期”
所谓“智能”,体现在你能否让缓存既够久(降带宽),又够新(保一致):
-
对静态资源(JS/CSS/图片):用 URL 版本化 + 长期缓存
Cache-Control: public, max-age=31536000
→ Nginx 几乎永不回源,无需 revalidate
-
对 HTML 或列表页等轻量可变内容:用短
s-maxage+ 条件校验自然生效Cache-Control: public, s-maxage=300, max-age=60
→ 浏览器 60 秒后刷新,Nginx 5 分钟内命中;过期后自动发
If-None-Match,源站返回304即复用 -
对强一致性接口(如权限状态):配合
must-revalidate或主动 purgeCache-Control: public, s-maxage=0, must-revalidate
→ 每次都校验,但应搭配业务侧精准清除(
proxy_cache_purge),而非依赖被动等待
如何确认机制真正在工作
不要看有没有“revalidate”,要看实际行为是否符合预期:
- 在日志中加入缓存状态:
log_format cache_log '$remote_addr - $upstream_cache_status "$request" $status'; access_log /var/log/nginx/cache.log cache_log;
- 观察响应头中的
$upstream_cache_status:-
HIT:未过期,直接返回 -
EXPIRED:已过期,Nginx 正在回源(若后端支持,此时发的是条件请求) -
REVALIDATED:收到304,复用了旧内容(说明 ETag/Last-Modified 生效) -
MISS:首次请求或缓存被清空
-
注意:
REVALIDATED状态仅在 Nginx 1.11.10+ 版本中可用,且需后端真实返回304—— 如果后端始终返回200,那永远看不到REVALIDATED,只会是EXPIRED或HIT。
不复杂但容易忽略











