proxy_cache_use_stale 不是独立开关,而是依赖完整缓存链路的授权降级机制;必须同时满足缓存已定义并启用、cache_key稳定、5xx响应被缓存(如proxy_cache_valid 500 502 503 504 1m),且精准配置http_500 http_502 http_503 http_504等可信故障信号,才能在后端崩溃时返回过期缓存避免中断。

只响应可信的后端故障信号
后端真正崩溃时,最稳定的表现是返回 502/503/504(网关错误、服务不可用、网关超时),有时也返回 500。这些由应用层主动发出,语义清晰、误判率低:
- 推荐写法:
proxy_cache_use_stale http_500 http_502 http_503 http_504; - 不建议加
error或timeout:连接拒绝、DNS 波动、单次读超时属于网络抖动,不是服务宕机,启用反而掩盖问题 - 如需支持缓存过期时的平滑过渡,可追加
updating,但必须同步开启proxy_cache_background_update on;,否则无效
确保旧内容“有得用、找得着、过得了期”
stale 不生成数据,只复用已有缓存。以下三项必须同时满足:
- 缓存区已定义并被引用:在
http块中配置proxy_cache_path /var/cache/nginx keys_zone=my_cache:512m inactive=3d use_temp_path=off;,并在location中写proxy_cache my_cache; - 缓存键稳定:用
proxy_cache_key "$scheme$host$request_uri";,剔除$args、$cookie、时间戳等易变字段,避免同一资源散列成多个 key - 错误响应也要进缓存:
proxy_cache_valid 500 502 503 504 1m;—— 没这句,5xx 根本不会落盘,后续就无旧内容可返;主响应也建议设合理有效期,如proxy_cache_valid 200 301 302 10m;
让托底不止于“返回旧数据”,而是“边服务边恢复”
返回陈旧响应只是起点。要实现用户无感过渡,需后台静默更新 + 并发控制:
- 开启异步刷新:
proxy_cache_background_update on;—— 返回 stale 的同时,Nginx 自动发起子请求拉新内容并写入缓存 - 防止并发击穿:
proxy_cache_lock on; proxy_cache_lock_timeout 3s;—— 同一 key 下,首个请求负责回源或触发后台更新,其余最多等待 3 秒后直接读新缓存或继续走 stale - 二者必须配合:没有
background_update,updating条件永不满足;没有cache_lock,多个并发可能同时刷爆上游
上线前必须验证是否真在生效
别只看状态码是不是 200。停掉 upstream 后,从客户端视角确认三件事:
- 响应头中出现
X-Cache: STALE(需提前配置add_header X-Cache $upstream_cache_status;) - 响应体与故障前完全一致:比如 HTML 页面没变、JS 文件二进制一致,不是空页、不是 Nginx 默认 502 页面
- 响应耗时极低(通常


















