关键在于启用proxy_cache_use_stale updating,配合proxy_cache_background_update on、proxy_cache_lock on及合理proxy_cache_valid和inactive时长,实现过期后秒级返回旧缓存并后台更新。

要让 Nginx 在缓存过期后仍秒级返回静态资源(如 JS、CSS、图片),同时后台悄悄拉取新版本,关键不是只开 proxy_cache_background_update on,而是整套协同配置——它本身不“无感”,得靠其他指令共同兜底。
必须显式启用陈旧缓存服务能力
仅开启 background update,Nginx 默认仍会拒绝用过期内容响应请求。真正起作用的是这行:
-
proxy_cache_use_stale updating —— 必须把
updating明确写进列表,否则后台更新触发了,用户却收不到旧缓存,等于白配; - 建议补全常见异常情形:
error timeout http_500 http_502 http_503 http_504,增强容错性; - 避免缓存 404 响应太久,尤其对静态资源:可单独设
proxy_cache_valid 404 10s,防止错误路径长期占位。
缓存有效期与后台更新节奏要匹配
后台刷新是否频繁,取决于你如何定义“过期”和“冷数据”:
安装并运行 Aperture(Lightning Labs 的 L402 闪电反向代理),用于创建 L402 付费墙、配置付费 API 端点、为其他代理托管付费内容或测试 L402 认证流程。
- proxy_cache_valid 200 302 10m —— 给正常静态资源设合理缓存时长(如 10 分钟),太短会导致高频刷新,太长则更新滞后;
-
proxy_cache_path ... inactive=30m —— 设为比
proxy_cache_valid更长(例如 30 分钟),确保缓存条目在无访问时才被清理,不干扰后台更新逻辑; - 对带哈希的静态资源(如
main.a1b2c3.js),可设更长有效期(如proxy_cache_valid 200 1h),因文件名变更即代表内容更新,无需频繁回源。
防止同一资源被并发刷爆后端
background update 本身不限流,高并发请求击中同一过期 key,可能瞬间发起数百次后台更新。需加锁控制:
- proxy_cache_lock on —— 确保同一缓存 key 只有一个请求真正回源;
-
proxy_cache_lock_timeout 2s —— 超时后不等待,直接走
proxy_cache_use_stale返回旧内容; - proxy_cache_lock_age 15s —— 锁释放后 15 秒内不再允许新更新,避免刚刷完又被抢锁重刷。
验证是否真正“无感”
上线后用几个简单方式确认效果:
- 加响应头观察:
add_header X-Cache-Status $upstream_cache_status,看到STALE表示正在用旧缓存+后台刷新; - curl 请求两次,间隔略超
proxy_cache_valid时间,第二次应立刻返回(状态码 200 +STALE),且上游日志中只出现一次新请求; - 检查 Nginx error 日志,若频繁报
cache lock failed或磁盘写入失败,说明proxy_cache_path路径不可写或空间不足。

















