proxy_cache_use_stale的作用是在upstream已返回502/503/504或连接失败时,返回本地过期缓存而非错误响应,避免服务中断;需配合cache_path、稳定cache_key、5xx缓存策略及background_update等机制才能生效。

proxy_cache_use_stale 本身不提高缓存命中率,也不修复后端故障,它的作用是在后端已出错(如返回 502/503/504 或连接失败)时,不让错误透传给用户,而是返回本地已有的、哪怕已过期的缓存内容——从而避免页面空白、接口报错、加载中断等直接影响用户体验的问题。
精准匹配真实故障信号
它只在明确的异常场景下启用降级,不是“有缓存就用”,而是按实际错误类型决定是否走 stale:
- 必须加 error:覆盖上游连接被拒、TCP 重置、DNS 解析失败等底层中断,这是后端彻底不可达的最常见表现
- 必须加 http_502 http_503 http_504:对应网关错误、服务不可用、网关超时,语义清晰、误判率低
- 不建议加 timeout:单次读超时可能是瞬时抖动,加入后易把本可成功的请求也降级
- 不建议加 http_500:多数崩溃是直接断连,不会主动返回 500;除非你确认后端会在宕机前统一输出 500
依赖缓存基础能力才能生效
stale 不生成缓存,只复用已有缓存。如果缓存链路没搭好,它就是个摆设:
- 缓存区必须定义且启用:http 块中配置 proxy_cache_path,并在 location 中通过 proxy_cache 引用对应 zone
- cache_key 必须稳定:推荐用 "$scheme$host$request_uri",剔除 ?t=、?v=、时间戳、随机参数等干扰字段,否则同一资源会散列成多个 key,无法复用
- 5xx 响应也要进缓存:加上 proxy_cache_valid 502 503 504 1m;,确保后端返回错误时也能落盘,后续才有“旧数据”可返
配合后台更新与并发控制实现平滑过渡
返回旧内容只是起点,真正提升可用性的是让用户无感过渡到新内容:
- 开启异步刷新: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
- 响应体(HTML / JSON / 图片二进制)和故障前完全一致,不是空页、不是 Nginx 默认错误页
- 响应耗时在几十毫秒内(远低于 proxy_read_timeout),说明确实绕过了回源











