proxy_cache_lock_timeout 是控制缓存 miss 时并发请求等待时间的参数,用于缓解回源穿透;需根据后端 p95 响应时间设定(如 p95≤300ms 设 1–1.5s),配合 proxy_cache_lock on、稳定 cache key 和 proxy_cache_use_stale 才生效。

proxy_cache_lock_timeout 不是用来处理“缓存失效”本身,而是控制缓存 未命中(MISS)时并发请求的等待行为——尤其在旧缓存过期、新内容尚未回源写入的窗口期,防止大量请求同时穿透到后端。它的合理设置,本质是为“缓存更新临界态”设计一道柔性闸门。
看后端真实响应能力定数值
这个值不能脱离后端性能拍脑袋定,必须基于全链路 P95 响应时间(含网络、DB、序列化等):
- 后端 P95 ≤ 300ms → 设为 1–1.5 秒(留出缓冲)
- 后端 P95 在 1.2–2 秒 → 推荐 3 秒
- 后端 P95 达到 4–6 秒(如聚合接口、报表导出)→ 可设 6–8 秒,但必须启用 stale 回退
- 避免设为 0 或 ≤100ms:几乎全部请求立刻绕过锁,击穿风险反而升高
- 不建议超过 10 秒:移动端易触发客户端重试,可能引发雪崩式请求
超时不是“放弃”,而是“有序放行”
超时后 Nginx 并不会让所有等待请求一起冲向后端,而是:只放行一个去回源,其余继续按 proxy_cache_use_stale 等策略处理。因此它不是“失败兜底”,而是“流量整形”:
- 超时前首个请求成功 → 所有等待请求直接读新缓存,零额外回源
- 超时后首个请求仍在进行 → 放行一个排队请求去补位回源(防长尾)
- 超时后首个请求已失败或超时 → 后续请求可立即返回 stale 缓存(需配置 use_stale)
单设 timeout 没用,必须配齐三要素
这个参数是协作型机制,离开以下三项,它基本不生效:
-
启用 lock:location 中必须有
proxy_cache_lock on; -
稳定 cache key:避免 query 参数、随机 t/v、Cookie 或 User-Agent 进入 key;推荐
proxy_cache_key "$scheme$host$uri"; -
启用 stale 回退:如
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;,确保等待中能安全返回旧内容
验证是否真正起效
加两行响应头便于观测:
add_header X-Cache-Status $upstream_cache_status;add_header X-Cache-Lock $upstream_cache_lock;
用 ab 或 wrk 并发压测(如 ab -c 50 -n 500 http://your-api/),观察响应头:
多数为 X-Cache-Status: HIT 或 UPDATING,极少出现 MISS;
出现 X-Cache-Lock: 1 表示该请求确实进入了锁等待队列。











