静默更新的核心是缓存过期后nginx仍返回旧缓存并后台异步刷新,需同时启用proxy_cache_use_stale updating和proxy_cache_background_update on,并配合分层缓存有效期(如10s基础+1m stale窗口)才能生效。

静默更新的核心是:缓存过期时,Nginx 仍返回旧缓存,同时在后台异步拉取新内容并更新缓存,用户无感知。 这个功能由 proxy_cache_background_update 控制,但必须配合合理的缓存有效期策略才能生效。
前提条件:启用 stale 状态支持
静默更新不是独立开关,它依赖于 proxy_cache_use_stale 指令中启用的“过期后仍可用”状态(如 updating)。只有当缓存已过期、且 Nginx 决定使用 stale 缓存时,才会触发后台更新。
- 必须设置
proxy_cache_use_stale updating;—— 这是激活静默更新的关键一步 - 建议同时配置
proxy_cache_use_stale error timeout http_500;提升容错性 - 若未启用
updating,即使打开proxy_cache_background_update,也不会执行后台更新
缓存有效期需分层设计
单靠 proxy_cache_valid 设置固定过期时间不够。要让静默更新起效,需区分“可直接返回的缓存”和“允许 stale 的窗口期”:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
- 用
proxy_cache_valid 200 302 10s;设定基础缓存时间为 10 秒 - 再用
proxy_cache_valid 200 302 1m;覆盖同状态码,表示最多可缓存 1 分钟(含 stale 时间) - 更推荐写法:
proxy_cache_valid 200 302 10s;+proxy_cache_valid 200 302 1m;实际取最长值,但关键是让 Nginx 知道“10 秒后进入 stale 阶段,但最多撑到 1 分钟” - 也可以用
proxy_cache_valid any 1m;简化,但需确保上游响应带Cache-Control或Expires时不会被覆盖
启用并验证 background update
开启后,Nginx 在 serving stale 响应的同时,会悄悄发起一个不带 If-Modified-Since / If-None-Match 的子请求去回源刷新缓存:
- 添加
proxy_cache_background_update on;即可启用(默认 off) - 该请求走的是内部子请求机制,不占用客户端连接,也不影响主响应头
- 可通过日志确认是否触发:开启
log_format cache '$upstream_cache_status';,命中 stale 时日志显示STALE,后台更新成功后下次请求会变为HIT - 注意:后台更新失败不会报错,也不会影响当前响应;失败时缓存保持 stale 状态直到下一次尝试
常见陷阱与调优建议
静默更新看似简单,但配置不当容易失效或引发问题:
- 上游服务必须支持重复请求且幂等——后台更新请求无用户上下文,不能依赖 session 或临时 token
- 避免在
location块中重复定义proxy_cache相关指令,继承关系易出错;建议统一在http或server块定义缓存区,location中只控制开关和策略 - 如果发现始终不触发后台更新,检查 access log 中
$upstream_cache_status是否出现STALE;没有则说明未进入 stale 阶段,可能是缓存时间没设短、或proxy_cache_use_stale updating缺失 - 高并发下后台更新可能堆积,Nginx 默认限制同一缓存 key 的并发更新请求数为 1,无需额外控制










