nginx后端宕机时返回旧缓存需协同proxy_cache_use_stale、缓存基础、错误捕获与键稳定性:必须配置error+http_502/503/504,禁用timeout和http_500;缓存区、稳定key、5xx缓存策略缺一不可;配合background_update和cache_lock实现平滑降级。

要让 Nginx 在后端挂掉时返回旧缓存,关键不是单独写 proxy_cache_use_stale,而是让它和缓存基础、错误捕获、键稳定性协同生效。它不修复后端,只确保用户不看到空白页或 502。
只启用真正反映后端挂掉的触发条件
后端彻底不可达时,典型表现是连接被拒或返回标准网关错误。应精准配置,避免把网络抖动也当成宕机:
-
必须加:
error(覆盖 connection refused、reset by peer 等底层中断) +http_502、http_503、http_504(服务不可用、网关超时等明确信号) -
不建议加:
timeout(单次读超时多为瞬时抖动)和http_500(多数崩溃不会主动返回 500,而是直接断连) -
按需加:
updating,但必须同步开启proxy_cache_background_update on,否则无效
确保旧缓存“存得住、找得准、用得上”
proxy_cache_use_stale 不生成内容,只复用已存在的过期缓存。以下三点缺一不可:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
- 缓存区已正确定义并启用:
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mycache:128m inactive=7d use_temp_path=off;,并在location中显式写proxy_cache mycache; - 缓存 key 稳定可靠:
proxy_cache_key "$scheme$host$uri";——剔除?t=、?v=、$args、Cookie 等动态字段,防止同一页面散列成多个 key - 5xx 响应必须进缓存:
proxy_cache_valid 502 503 504 1m;,否则后端返回 503 时根本不会落盘,后续 stale 就无数据可取;主响应也建议设合理有效期,如proxy_cache_valid 200 301 302 10m;
让降级更平滑:边返回旧内容,边悄悄拉新
单纯返回老数据只是第一步。要让用户无感过渡到新内容,还需两层保障:
- 开启后台异步刷新:
proxy_cache_background_update on;→ 返回 stale 的同时,Nginx 自动发起子请求刷新缓存 - 防止并发击穿:
proxy_cache_lock on;+proxy_cache_lock_timeout 3s;→ 同一 key 下,首个请求负责回源或触发更新,其余请求最多等 3 秒后直接读缓存(或继续走 stale) - 暴露状态便于验证:
add_header X-Cache $upstream_cache_status;→ 客户端看到X-Cache: STALE才算真正生效
上线前必须验证的三件事
别只看 HTTP 状态码是不是 200。停掉 upstream 后,从真实客户端视角确认:
- 响应头中是否含
X-Cache: STALE - 响应体(HTML / JSON)是否与故障前完全一致,不是空页、不是默认 502 页面、也不是错误提示 JSON
- 响应耗时是否远低于
proxy_read_timeout(比如设为 3s,实际返回在 50ms 内),说明确实绕过了回源










