Nginx可通过proxy_cache_use_stale配合proxy_cache_background_update和proxy_cache_lock实现后端故障时返回陈旧响应并后台静默更新:需启用http_500/502/503/504触发、确保缓存已存在且key稳定、将5xx响应纳入缓存,并验证停上游后请求仍快速返回。

要让 Nginx 在后端故障时自动返回陈旧响应并悄悄恢复新鲜内容,关键不是“等它好”,而是用 proxy_cache_use_stale 搭配后台更新机制,构建一条“先保服务、再换内容”的自愈链路。
只启用可信的故障触发条件
源站真正崩溃时,通常会稳定返回 502/503/504,偶尔是 500。这些是后端主动发出的明确信号,可信度高:
- 写入
proxy_cache_use_stale http_500 http_502 http_503 http_504; - 不加
error或timeout:网络抖动、DNS 延迟或单次连接失败不该触发降级,否则会掩盖真实问题 - 如需支持缓存过期时的平滑过渡,可追加
updating,但必须配套开启后台更新(见下文)
确保陈旧内容“有得用、找得着、能复用”
stale 不是凭空生成内容,它依赖已有缓存条目存在且结构稳定:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
-
缓存必须已存住:确认
proxy_cache_path已定义 keys_zone(如my_cache:10m),且对应 location 中启用了proxy_cache my_cache; -
缓存键必须稳定:用
proxy_cache_key "$scheme$host$request_uri";,剔除$args、$cookie、时间戳等易变字段,避免同一资源被拆成多个 key -
错误响应也要进缓存:加一句
proxy_cache_valid 500 502 503 504 1m;,让 Nginx 把 5xx 响应也存下来——后续 stale 才有“旧内容”可返
让自愈真正发生:后台刷新 + 请求锁协同
返回陈旧内容只是起点;自愈的核心在于“用户无感地拿到新数据”。这需要两个指令严格配合:
-
开启后台更新:
proxy_cache_background_update on;—— Nginx 在返回 stale 响应的同时,自动发起一个低优先级子请求去 upstream 拉新内容并写入缓存 -
防止并发刷爆上游:
proxy_cache_lock on;和proxy_cache_lock_timeout 3s;—— 当第一个请求触发后台更新时,其余并发请求会等待锁释放(最多等 3 秒),然后直接读取刚刷新好的新缓存,不再重复回源
缺一不可:没有 background_update,updating 条件永不满足;没有 cache_lock,多个请求可能同时触发多个后台子请求,造成上游压力倍增。
从客户端视角验证是否真在自愈
别只看状态码,要确认三件事:
- 停掉上游服务后,请求仍快速返回(耗时 X-Cache: STALE(需提前配置
add_header X-Cache $upstream_cache_status;) - 响应体与故障前完全一致(比如 JSON 字段、图片二进制、HTML 结构),不是空页或 Nginx 默认错误页
- 稍等几秒后再次请求,响应头变为
X-Cache: HIT,且内容已更新——说明后台刷新成功,自愈完成

















