Nginx 后端宕机时返回旧缓存需配置 proxy_cache_use_stale http_500 http_502 http_503 http_504,配合 proxy_cache_valid 5xx、稳定 cache_key、background_update 与 cache_lock 实现自愈闭环。

要让 Nginx 在后端节点宕机时自动返回可用的旧缓存内容,关键不是“等故障发生再响应”,而是提前构建一条可触发、可复用、可验证的缓存自愈链路。proxy_cache_use_stale 是这条链路的“授权开关”,它不生成缓存,也不决定缓存是否存在,只在特定失败条件下允许使用已过期但尚存的缓存项。
精准配置 stale 触发条件
后端节点宕机最典型的表现是明确返回 5xx 错误(如全部 upstream server 进程退出、健康检查失败或被拦截),而非网络抖动或瞬时超时。应只启用高可信度的触发项:
- 写入 proxy_cache_use_stale http_500 http_502 http_503 http_504; —— 这四类是后端主动发出的故障信号,语义清晰、误判率低
- 避免添加 error 或 timeout:网络瞬断、DNS 波动或单次读取延迟可能被误判为“节点宕机”,导致本可成功的请求也走降级,反而掩盖真实问题
- 如需后台静默刷新,可追加 updating,但必须同步开启 proxy_cache_background_update on;,否则该参数无效
确保缓存本身“存得住、找得着、过得了期”
stale 生效的前提是:缓存条目真实存在、key 稳定、且已过期。常见失效都源于基础配置疏漏:
安全更新和维护 CLI Proxy API(CPA)部署与配置。用于 CPA 镜像升级、配置变更、认证目录兼容修复、上线验证与回滚。适用于用户提到“CPA 更新/升级/配置改了/容器重建/回滚”等场景。
- 必须定义 proxy_cache_path 并在 location 中通过 proxy_cache my_cache; 显式引用对应 keys_zone
- proxy_cache_key 要稳定:推荐用 "$scheme$host$request_uri",剔除 $args、$time_iso8601、$request_id 等动态字段,防止同一资源被拆成多个 key
- proxy_cache_valid 必须覆盖错误响应:加一句 proxy_cache_valid 500 502 503 504 1m;,确保 5xx 响应也能进缓存——这是后续 stale 复用的基础
- 缓存有效期不宜过短(如仅 10s):若还没等节点宕机,缓存就已被清理,stale 就无内容可返
搭配后台更新与锁机制实现“自愈”闭环
返回陈旧内容只是起点;真正实现“自愈”,需要让新内容在后台悄然就位:
- 开启 proxy_cache_background_update on;:当 stale 响应发出时,Nginx 自动发起异步子请求拉取新响应并写入缓存;失败不影响当前响应,也不阻断后续 stale 复用
- 启用 proxy_cache_lock on; 和 proxy_cache_lock_timeout 3s;:防止大量并发请求在缓存失效瞬间集体击穿后端,第一个请求负责回源,其余等待或直接走 stale
- 通过 add_header X-Cache $upstream_cache_status; 暴露状态,便于监控识别是否命中 STALE 或 UPDATING
从客户端视角验证是否真自愈
停掉所有 upstream 节点后,不能只看状态码是否为 200,要确认三件事:
- 响应头中出现 X-Cache: STALE(前提是已配置 add_header)
- 响应体(body)与宕机前完全一致:比如一个 JSON 接口返回的数据结构、一个图片的二进制内容,不是空页、不是 Nginx 默认 502 页面
- 响应耗时在几十毫秒内(远低于 proxy_read_timeout,如设为 3s,实测约 40–80ms),说明确实绕过了回源,未等待后端

















