proxy_cache_use_stale 配合 http_500-504 可在源站故障时返回过期缓存,实现可控降级;需确保缓存存在、key稳定、5xx响应被缓存,并通过X-Cache头和响应体验证效果。

当源站返回 500、502、503 或 504 等错误时,proxy_cache_use_stale 可让 Nginx 绕过校验,直接返回已过期但尚存的缓存内容——这是实现“服务不中断”的关键降级手段,不是兜底,而是可控的可用性保障。
明确启用哪些 stale 触发条件
针对源站 50x 崩溃场景,只需指定对应状态码参数即可,无需开启全部:
-
proxy_cache_use_stale http_500 http_502 http_503 http_504;——仅在后端明确返回这些错误时启用 stale - 避免加
error或timeout,否则网络抖动或超时也会触发,可能放大异常影响 - 若同时希望后台更新缓存时不阻塞用户,可额外加上
updating(需配合proxy_cache_background_update on)
确保缓存基础链路完整有效
stale 不是独立开关,它依赖缓存本身“存在且过期”才能生效。常见失效原因包括:
- 未定义
proxy_cache_path中的keys_zone,或 location 中未用proxy_cache my_cache引用 -
proxy_cache_key包含了易变字段(如时间戳、随机参数),导致相同逻辑请求无法命中同一缓存项 -
proxy_cache_valid没有覆盖 5xx 响应:建议加一句proxy_cache_valid 500 502 503 504 1m;,确保错误响应也能进缓存,后续才可被 stale 复用
验证 stale 是否真实起效
不能只看日志或状态码,要从客户端视角确认行为:
- 停掉上游服务(如
systemctl stop app-server),发起请求,观察响应头中是否出现X-Cache: STALE(需提前配置add_header X-Cache $upstream_cache_status;) - 对比故障前后响应体(body)是否一致,确认返回的是“原样旧内容”,而非空响应或默认错误页
- 响应耗时应显著低于
proxy_read_timeout(例如设为 3s,但实际返回在 50ms 内),说明确实绕过了回源
配合后台更新与锁机制提升体验
单纯返回过期内容只是第一步;更进一步,应让用户无感地拿到“正在刷新的新内容”:
- 开启
proxy_cache_background_update on;,使 Nginx 在返回 stale 同时,悄悄向后端发起异步更新 - 启用
proxy_cache_lock on;和proxy_cache_lock_timeout 3s;,防止大量并发请求在缓存失效瞬间集体击穿源站 - 对关键接口,可结合
proxy_cache_bypass $arg_nocache;提供手动刷新入口(如带?nocache=1的调试请求)


















