proxy_cache_use_stale 并非使缓存可靠,而是后端故障时复用已存旧缓存;仅对500/502/503/504等高可信错误启用,需配合cache路径、key、valid配置及background_update、cache_lock等机制,并通过x-cache头验证stale状态。

proxy_cache_use_stale 不是“让缓存变可靠”的开关,而是让 Nginx 在后端出问题时,敢把已有的旧缓存交出去——前提是缓存本身已经可靠地存住了、找得准、判得清过期与否。
只对高可信故障信号启用 stale
后端真正崩溃时,最稳定的表现是返回 500/502/503/504 这类由应用主动发出的状态码。这些信号语义明确、误判率低,适合直接用于 stale 触发:
- 写 proxy_cache_use_stale http_500 http_502 http_503 http_504; ——覆盖进程异常、网关中断、服务不可用等典型崩溃场景
- 不加
error或timeout:连接拒绝、DNS 失败、单次读超时多属瞬时抖动,盲目启用会把本可成功的请求也降级 - 如需后台静默更新,必须额外加上
updating,且同步开启proxy_cache_background_update on;,否则该参数无效
缓存必须“存得住、找得准、过得了期”
stale 只复用,不生成。若缓存链路断裂,再精准的 stale 配置也无内容可托底:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
- 缓存区要正确定义并被引用:
proxy_cache_path /var/cache/nginx/mycache levels=1:2 keys_zone=mycache:256m inactive=1h use_temp_path=off;,并在location中写proxy_cache mycache; - 缓存键必须稳定:
proxy_cache_key "$scheme$host$request_uri";——剔除$args、?t=、?v=、Cookie 等动态干扰字段 - 错误响应也要进缓存:
proxy_cache_valid 500 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才说明机制真在运行
上线前必须验证的三件事
停掉 upstream 后,从客户端视角确认:
- 响应头中出现
X-Cache: STALE - 响应体(HTML/JSON)和故障前完全一致,不是空页、不是 Nginx 默认错误页
- 响应耗时在几十毫秒内,远低于
proxy_read_timeout,证明确实绕过了回源










