Nginx 通过 proxy_cache_use_stale 在后端宕机时返回已缓存旧内容保障可用性,需配置四类5xx错误、error及updating(配合background_update),并确保cache_path、proxy_cache、cache_key和cache_valid完整生效。

在后端服务宕机时,Nginx 可以通过 proxy_cache_use_stale 返回已缓存的旧内容,维持用户访问不中断。这不是“重试”或“兜底”,而是有策略地复用本地已有缓存,核心目标是保障可用性。
只对真实后端故障启用 stale
stale 应响应明确、可信的崩溃信号,避免因网络抖动误触发:
- 必须包含:http_500 http_502 http_503 http_504——这四类由后端主动返回,语义清晰,代表服务不可用
- 建议包含:error——覆盖连接被拒、上游重置、DNS 失败等底层中断
- 慎用:timeout——单次读超时可能是瞬时抖动,非节点真正宕机,盲目启用会放大陈旧内容暴露面
- 按需添加:updating——需配合 proxy_cache_background_update on 使用,用于缓存正刷新时临时托底
确保缓存本身“存得住、找得准、过得了期”
stale 不生成缓存,只复用已存在但过期的内容。以下任一缺失,配置即失效:
- 定义缓存区:proxy_cache_path 必须在 http 块中声明,例如:
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:128m inactive=1h use_temp_path=off; - 启用缓存作用域:location 中必须写 proxy_cache my_cache;(名称与 keys_zone 严格一致)
- 使用稳定 cache key:proxy_cache_key "$scheme$host$request_uri"; ——剔除 $args、$cookie_、时间戳等动态字段,防止同一资源生成多个 key
- 让错误响应也能进缓存:proxy_cache_valid 500 502 503 504 1m; ——否则后端返回 503 时根本不会落盘,stale 就无内容可返
搭配后台更新与请求锁,实现无感过渡
返回旧内容只是起点,关键是要让用户在无感知中完成新内容加载:
- 开启异步刷新:proxy_cache_background_update on; —— stale 响应发出的同时,Nginx 自动发起子请求拉取新内容并更新缓存
- 防止并发击穿:proxy_cache_lock on; proxy_cache_lock_timeout 3s; —— 同一缓存 key 下,仅首个请求负责回源或触发后台更新,其余请求直接返回 stale 或刚刷新好的内容
- 暴露状态便于验证:add_header X-Cache $upstream_cache_status; —— 故障时看到 X-Cache: STALE 才说明机制真实生效
上线前必须验证的三件事
停掉 upstream 后,从真实客户端视角确认:
- 响应头中是否含 X-Cache: STALE(而非 MISS、EXPIRED 或空)
- 响应体内容是否与故障前完全一致——不是空页、不是 Nginx 默认 502 页面、也不是结构错乱的 JSON
- 响应耗时是否显著降低(如 proxy_read_timeout 设为 3s,实测返回在 40–80ms 内),证明确实绕过了回源











