proxy_cache_use_stale updating 需与 background_update、cache_lock、cache_valid 等协同生效,构成“过期秒回+后台刷新”机制,缺一不可;否则仅配置无效。

要让 proxy_cache_use_stale updating 真正提升高并发下的用户体验,关键不是单独加这行参数,而是把它作为“过期后秒回旧内容 + 后台静默刷新”机制的授权开关,嵌入一套协同生效的缓存策略中。它本身不发起请求、不控制锁、不定义有效期,只决定“过期了敢不敢发”。缺了配套,写了也白写。
必须搭配 background_update 和明确的有效期
updating 参数只有在缓存已过期、且 Nginx 被允许启动后台子请求时才起作用:
- 必须显式开启:
proxy_cache_background_update on;—— 没它,Nginx 就不会悄悄拉新内容 - 必须设好新鲜窗口:
proxy_cache_valid 200 302 15s;—— 这是判断“是否过期”的依据,没它 updating 就无从触发 - 推荐补宽限期:
proxy_cache_valid 200 302 5m;(同一状态码可多写一行)—— 前者是“强新鲜期”,后者是“stale 宽限期”,让过期后仍可复用
一定要配 cache_lock 防止并发击穿
updating 只管“能不能返回旧数据”,不管“谁来刷新”。高并发下若不加锁,一个过期 key 可能引发几十次重复回源:
安装并运行 Aperture(Lightning Labs 的 L402 闪电反向代理),用于创建 L402 付费墙、配置付费 API 端点、为其他代理托管付费内容或测试 L402 认证流程。
- 启用锁:
proxy_cache_lock on;—— 同一 cache key 下,只允许一个请求真正回源或触发更新 - 设抢锁超时:
proxy_cache_lock_timeout 2s;—— 超时后直接走 stale,不卡主响应 - 加冷却时间:
proxy_cache_lock_age 10s;—— 锁释放后 10 秒内禁止新请求抢锁重刷,避免抖动
确保 stale 有东西可返,不是空承诺
stale 不生成缓存,只复用已存在但过期的内容。以下三点缺一不可:
- 缓存区已正确定义:
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:256m inactive=10m; - location 中明确启用:
proxy_cache my_cache; - cache_key 稳定可靠:
proxy_cache_key "$scheme$host$request_uri";—— 删掉$args、时间戳、随机参数等干扰项 - 错误响应也要进缓存:
proxy_cache_valid 500 502 503 504 30s;—— 否则上游挂了返回 503,根本没缓存,stale 就无数据可用
上线前必须验证的真实行为
别只看配置是否加载成功,重点确认用户侧是否真获得“秒回+后台刷新”效果:
- 加响应头:
add_header X-Cache-Status $upstream_cache_status;—— 第二次请求(略超 proxy_cache_valid 时间)应看到STALE - 查上游日志 —— 应只出现一次新请求,而非每次都有
- 测响应耗时 —— STALE 响应应在 20–80ms 内返回,远低于
proxy_read_timeout - 检查响应体 —— 必须和故障前完全一致,不是空页、不是默认 502 页面










