Nginx中proxy_cache_use_stale如何巧妙应对源站崩溃实现服务平滑降级?
- 内容介绍
- 文章标签
- 相关推荐
本文共计704个文字,预计阅读时间需要3分钟。
直接结论:
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 确认缓存区真实状态。
本文共计704个文字,预计阅读时间需要3分钟。
直接结论:
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 确认缓存区真实状态。

