proxy_cache_use_stale 不是兜底开关,而是依赖完整缓存链路的可控降级策略;需精准配置http_500-504触发条件、确保5xx被缓存、key稳定且缓存存在,否则源站崩溃仍返回502。

直接结论:proxy_cache_use_stale 不是“兜底开关”,而是需要完整缓存链路支撑的降级策略;只配它,源站一崩照样 502。
proxy_cache_use_stale 触发条件必须精准匹配错误类型
它不会自动感知“源站崩了”,只在你明确列出的条件下才放行陈旧缓存。常见误配是加一堆参数却没覆盖真实故障:
- 只想要 5xx 故障时返回 stale?就写
proxy_cache_use_stale http_500 http_502 http_503 http_504;—— 不要混进error或timeout,否则一次网络抖动或 DNS 延迟就触发,把本可成功的请求也降级了 - 若后端常因连接拒绝(connection refused)或 reset by peer 崩溃,才需加
error;但要清楚这会包含更多非业务性失败 -
updating只在配合proxy_cache_background_update on;时才有意义,单独写它不生效
stale 生效的前提:缓存本身得存在、能命中、且被允许缓存 5xx
很多人配完发现故障时还是 502,问题往往出在缓存链路断了:
-
proxy_cache_valid必须覆盖 5xx 状态码,例如:proxy_cache_valid 500 502 503 504 1m;—— 否则 Nginx 根本不会把错误响应存进缓存,后续也就无 stale 可用 -
proxy_cache_key不能含易变字段(如$time_iso8601、$request_id),否则相同 URL 每次生成不同 key,缓存无法复用 - 首次请求时缓存为空,此时即使配置了
proxy_cache_use_stale,Nginx 仍会回源失败并透传错误 —— 所以必须确保关键接口有稳定流量提前“预热”缓存
如何验证 stale 是否真在起作用,而不是假象
别信日志里的一句 “STALE”,要从客户端视角确认行为:
- 停掉 upstream(比如
systemctl stop app-server),发起请求,检查响应头中是否有X-Cache: STALE(需先配置add_header X-Cache $upstream_cache_status;) - 对比故障前后响应体(
body)是否完全一致 —— 如果变了,说明返回的不是缓存内容,可能是默认 error_page 或空响应 - 响应耗时应远低于
proxy_read_timeout(比如设为 3s,实际返回在 20–80ms),否则说明仍在等后端,stale 并未绕过校验
最常被忽略的一点:stale 不等于“永远可用”。如果缓存项已被 inactive 清理(比如 proxy_cache_path ... inactive=10m;),或磁盘满导致缓存写失败,那再怎么配 proxy_cache_use_stale 都无效。得定期检查 /var/log/nginx/cache.log 或用 du -sh /var/cache/nginx 确认缓存区真实状态。


















