要让nginx缓存失效时返回旧内容并后台更新,必须启用proxy_cache_use_stale updating及错误码、设置proxy_cache_valid过期时间、开启proxy_cache_lock防击穿,并通过x-cache头和文件mtime验证生效。

要让 Nginx 在缓存失效时返回旧内容并后台静默更新,核心不是只开 proxy_cache_background_update on,而是必须把 updating 参数作为“授权开关”嵌入到整个缓存容灾链里。它不负责发起请求,只决定“能不能用过期内容”,而真正触发后台拉新的是这个授权成立后的连带行为。
必须显式启用 proxy_cache_use_stale updating
这是整个机制的启动前提。没有 updating,Nginx 遇到过期缓存默认阻塞等待回源,根本不会返回旧内容,后台更新也就无从谈起。
- 写法必须包含
updating:例如proxy_cache_use_stale updating error timeout http_500 http_502 http_503 http_504; - 仅写
updating不够健壮;补上错误类参数,才能覆盖回源失败时仍可用旧缓存的场景 - 如果这行缺失或漏掉
updating,即使开了background_update,用户也收不到旧缓存,后台子请求永远不会出发
必须搭配明确的 proxy_cache_valid 过期时间
没有有效期,就没有“失效”概念,也就谈不上“失效后是否允许返回旧内容+后台更新”。
- 为常见状态码设有效期,例如:
proxy_cache_valid 200 302 10s; - API 类接口建议设 10s~2m;带哈希的静态资源可设 1h+
- 务必单独控制 404:
proxy_cache_valid 404 10s;,避免无效缓存长期占位
必须开启 proxy_cache_lock 防击穿
多个请求同时命中同一过期 key,若不加锁,可能瞬间触发几十次后台回源,反而压垮上游。
-
proxy_cache_lock on;—— 只允许一个请求真正回源 -
proxy_cache_lock_timeout 5s;—— 锁等待超时后,直接走 stale 返回旧内容 - 可选加固:
proxy_cache_lock_age 15s;,锁释放后 15 秒内禁止重复更新
验证是否生效的关键信号
别只看配置是否写了,重点观察运行时表现:
- 停掉后端服务后,用户请求仍能快速返回(响应时间远低于
proxy_read_timeout) - 响应头中出现
X-Cache: STALE(需配置add_header X-Cache $upstream_cache_status;) - 缓存目录中对应 key 的文件修改时间持续更新,说明后台刷新正在运行











