proxy_cache_background_update 解决缓存过期时请求阻塞与回源压力问题:启用后立即返回过期缓存并后台异步更新,需配合 proxy_cache_use_stale updating 等指令协同生效。

proxy_cache_background_update 指令让 Nginx 在缓存过期后,仍可继续返回旧缓存内容,同时在后台悄悄拉取最新资源并更新缓存——用户完全无感知,既避免了“缓存雪崩”式回源压力,也消除了“缓存穿透”导致的响应延迟。
它解决什么问题?
默认情况下,当缓存过期,Nginx 会阻塞后续请求,全部等待新响应返回后再统一返回给客户端。这会造成:多个并发请求同时回源、上游压力陡增;部分用户明显感受到变慢。
启用 proxy_cache_background_update on 后,只要缓存存在(哪怕已过期),Nginx 就立即返回它;同时仅派一个后台子请求去刷新缓存,其他请求不受影响。
必须配合的关键指令
该功能不是独立生效的,需与以下指令协同使用:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
- proxy_cache_use_stale updating:明确允许在“正在后台更新”的状态下,继续使用过期缓存。缺它则 background update 不触发;
-
proxy_cache_valid:定义缓存有效期(如
200 302 10m),这是判断“是否过期”的依据; - proxy_cache_lock on(推荐):防止多个相同请求同时触发后台更新,确保只有一个后台刷新任务;
- proxy_cache_lock_timeout(可选):设置锁等待超时,避免个别请求卡死。
典型配置示例
一段实用的最小化配置片段:
proxy_cache_path /var/cache/nginx/mycache levels=1:2 keys_zone=mycache:10m max_size=1g;
server {
location /api/ {
proxy_pass https://backend;
proxy_cache mycache;
proxy_cache_valid 200 302 5m;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_background_update on;
proxy_cache_lock on;
proxy_cache_lock_timeout 5s;
}
}
注意:updating 必须出现在 proxy_cache_use_stale 列表中,否则即使开了 background update,Nginx 也不会用过期缓存服务请求。
要注意的边界情况
这个机制并非万能,需留意:
- 后台更新失败时,旧缓存仍会继续提供服务(因启用了
updating),但不会自动重试,需靠下次请求再次触发; - 不适用于对实时性要求极高的接口(比如秒杀库存、支付状态),因为用户看到的仍是几分钟前的数据;
- 日志中无法直接区分“返回的是新鲜缓存”还是“返回的是过期缓存+后台更新中”,需结合
$upstream_cache_status变量观察(值为REVALIDATED表示命中过期缓存且后台已启动更新); - 若后台更新耗时很长,而同一资源请求持续不断,Nginx 会复用同一个后台更新任务,不会重复发起。

















