核心是构建“后端不可用→自动回源缓存→缓存失效则返回兜底响应”的柔性降级链:通过proxy_next_upstream与proxy_cache_use_stale联动实现故障时返回陈旧缓存并异步刷新,健康度低时动态调整缓存时效,最终由error_page触发静态兜底,同时严控vary、禁用兜底缓存、合理设置inactive时间。

核心在于让 upstream 的可用性状态直接驱动 proxy_cache 的行为,形成“后端不可用 → 自动回源缓存 → 缓存失效则返回兜底响应”的柔性链条,而非简单开关式降级。
用 proxy_next_upstream 触发缓存回退
当 upstream 节点全部异常(超时、502/504 等)时,Nginx 默认会返回错误。但可配置它跳过失败节点后,主动转向缓存层:
- 设置 proxy_next_upstream error timeout http_502 http_503 http_504,确保故障传播可控
- 配合 proxy_cache_use_stale error timeout updating http_502 http_503 http_504,允许在上游出错时,直接返回陈旧缓存(stale),同时后台异步刷新
- 若缓存也过期或不存在,则靠 error_page 502 503 504 = @degrade 进入兜底逻辑
基于 upstream 健康状态动态调整缓存策略
利用 nginx-upsync-module 或 OpenResty 的 Lua 模块获取实时健康节点数,映射为变量,再影响缓存行为:
安全更新和维护 CLI Proxy API(CPA)部署与配置。用于 CPA 镜像升级、配置变更、认证目录兼容修复、上线验证与回滚。适用于用户提到“CPA 更新/升级/配置改了/容器重建/回滚”等场景。
- 例如:当 $upstream_health_ratio (健康节点占比低于三成),自动缩短 proxy_cache_valid 200 302 1m(从 10m 缩至 1 分钟),加快缓存更新节奏
- 若健康节点数为 0,触发 proxy_cache_bypass $upstream_down,强制绕过缓存直连(此时虽无节点,但可被 error_page 捕获转入降级)
- 该变量可通过 Lua 在 init_worker_by_lua_block 中定期拉取 Consul/Nacos 实例状态并写入 shared dict
构建三级响应管道:实时 → 缓存 → 静态兜底
一条请求的完整柔性路径应具备明确优先级和自动降级能力:
- 第一级:实时转发 —— 正常走 proxy_pass http://backend,带完整 header 透传
- 第二级:缓存服务 —— 上游失败时,由 proxy_cache_use_stale 提供 stale 响应;后台用 proxy_cache_background_update on 异步刷新
- 第三级:静态兜底 —— 缓存不可用时,@degrade location 返回预置 JSON 或 HTML 片段,甚至可 alias /var/www/degrade/app.json 直接读文件,零依赖后端
关键细节:避免缓存污染与误降级
柔性不等于随意,需守住两个边界:
- Vary 头必须严谨:若后端按 X-User-ID 返回不同内容,缓存必须包含 proxy_cache_key $scheme$host$request_uri$http_x_user_id,否则用户 A 看到用户 B 的缓存
- 不缓存降级响应本身:在 @degrade location 中显式添加 add_header Cache-Control "no-store, no-cache",防止兜底页被 CDN 或浏览器长期缓存
- inactive 时间要短于业务容忍窗口:比如订单查询要求数据新鲜度 ≤ 30 秒,proxy_cache_path ... inactive=25s,避免 stale 数据滞留过久










