proxy_cache_background_update的作用是缓存过期后立即返回旧内容并后台刷新,但不控制并发更新;需配合proxy_cache_lock等配置实现单次更新共享,避免回源风暴。

proxy_cache_background_update 的作用是:当缓存已存在但已过期(比如 proxy_cache_valid 1m 到期),Nginx 仍会把旧响应立刻返回给客户端,同时在后台悄悄发起一次新请求去刷新缓存。这能显著降低用户感知延迟,但默认行为下,**每次过期请求都会触发一次后台更新**——如果同一缓存键被大量并发请求击中(例如热点 URL 突然涌入数千 QPS),就可能瞬间产生同等数量的后台更新连接,压垮上游服务。
核心问题:不是“要不要更新”,而是“谁来更新”
关键不在于禁用 background update,而在于让多个并发请求**共享一次更新动作**。Nginx 本身不提供“只允许一个进程/线程执行更新”的原生锁机制,但可通过组合配置实现效果等效的控制:
-
启用 proxy_cache_lock:这是最直接的手段。它确保对同一个缓存键,只有一个请求能进入后端取新数据;其余同键请求要么等待(
proxy_cache_lock_timeout内),要么直接返回陈旧缓存(配合proxy_cache_use_stale updating)。 -
合理设置 proxy_cache_lock_timeout 和 proxy_cache_lock_age:例如设为
proxy_cache_lock_timeout 3s、proxy_cache_lock_age 5s。前者限制等待锁的最大时长,后者决定锁释放后多久才允许下一次更新尝试——避免刚更新完立刻又被抢锁重刷。 - 配合 proxy_cache_use_stale updating:让等待锁超时或未抢到锁的请求,也能安全返回当前缓存内容(即使略旧),而不是全部回源。
为什么不能只靠 background_update?
proxy_cache_background_update on 本身不带并发抑制逻辑。它只是“过期即发后台请求”,不管此刻是否有其他请求也在做同样的事。在高并发场景下,这就变成“每秒 N 次重复回源”,和没开缓存差别不大。真正起限流作用的是 proxy_cache_lock 及其配套参数,background_update 只负责“不阻塞用户”,不负责“不压垮后端”。
安装并运行 Aperture(Lightning Labs 的 L402 闪电反向代理),用于创建 L402 付费墙、配置付费 API 端点、为其他代理托管付费内容或测试 L402 认证流程。
实际配置建议(精简有效)
以下片段可直接嵌入 location 块:
proxy_cache_lock on;-
proxy_cache_lock_timeout 2s;(短超时,避免客户端久等) -
proxy_cache_lock_age 10s;(10 秒内同一键只允许一次后台更新) -
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;(覆盖所有常见失败情形) -
proxy_cache_background_update on;(保留快速响应能力)
额外加固点:从源头减少更新频次
后台更新压力本质来自缓存过期太频繁。可结合业务权衡:
- 对读多写少的接口,适当延长
proxy_cache_valid,比如从 1 分钟提到 5–10 分钟; - 用
inactive=1h替代inactive=1w,让冷资源更快退出,热资源更稳定驻留; - 若上游支持 ETag/Last-Modified,保留
proxy_ignore_headers Cache-Control Expires要谨慎——有时上游的缓存头比 Nginx 自设的更精准。










