要实现nginx缓存过期后秒级返回旧内容并后台更新,必须协同配置:①启用proxy_cache_use_stale updating等参数授权返回过期内容;②明确定义proxy_cache_valid有效期;③开启proxy_cache_lock防并发回源;④添加x-cache-status响应头验证状态。

要让 Nginx 在缓存过期后秒级返回旧内容,同时后台悄悄拉取新版本,不能只开 proxy_cache_background_update on,必须几项配置协同生效。它不是“自动触发”的功能,而是一套有明确依赖关系的缓存容灾机制。
必须启用 proxy_cache_use_stale updating
这是最核心、最容易被忽略的一环。Nginx 默认遇到过期缓存会阻塞等待回源,除非你明确授权它“允许在更新中返回旧内容”。
- 必须写全
updating参数,例如:proxy_cache_use_stale updating error timeout http_500 http_502 http_503 http_504 - 没有
updating,即使开了 background update,用户也收不到旧缓存,后台请求也就失去意义 - 对 404 响应建议单独控制缓存时长,如
proxy_cache_valid 404 10s,避免无效条目长期占位
明确定义缓存有效期(proxy_cache_valid)
没有有效期,Nginx 就无法判断“是否过期”,整个异步更新逻辑就无从谈起。
- 为常见状态码设合理时长,例如:
proxy_cache_valid 200 302 10m - API 类接口可按业务节奏设更短时间(如 30s~2m),平衡新鲜度与压力
- 带哈希的静态资源(如
app.a1b2c3.js)可设更长有效期(如 1h),因文件名变更即代表内容更新
防止并发重复回源(proxy_cache_lock)
高并发击中同一过期 key,可能瞬间发起大量后台请求,拖垮上游或浪费带宽。
- 开启
proxy_cache_lock on:确保同一缓存 key 只有一个请求真正回源 - 设置
proxy_cache_lock_timeout 5s:超时后不等待,直接走 stale 路径返回旧内容 - 可选加
proxy_cache_lock_age 15s:锁释放后 15 秒内禁止新更新,防抖动
验证是否真正生效
上线后靠响应头和行为观察快速确认机制运行正常。
- 加响应头:
add_header X-Cache-Status $upstream_cache_status -
X-Cache-Status: HIT→ 缓存新鲜可用;STALE→ 正在用旧内容 + 后台刷新中 - 用
curl连续请求两次,间隔略超proxy_cache_valid时间,第二次应秒回且带STALE,上游日志中只出现一次新请求











