proxy_cache_lock_timeout控制缓存miss时等待首个回源完成的最长时间,超时后等待请求放弃等待并各自回源;需配合proxy_cache_lock on、稳定cache_key及proxy_cache_use_stale updating协同生效,推荐值3–8秒,依据后端p95响应时间设定。

proxy_cache_lock_timeout 控制的是:当多个请求同时命中一个未缓存或已过期的 key,且启用了 proxy_cache_lock on 时,后续请求在锁队列中最多等待多久——超时后就放弃等待、各自回源。它不控制锁本身持有多久,也不影响已命中缓存的请求。
它只在这些条件下生效
- 请求是缓存未命中(MISS),比如首次访问或 TTL 到期
- 配置了
proxy_cache_lock on - 多个请求落在同一个 cache key 上
- 后端尚未完成响应并写入缓存
此时 Nginx 只放行第一个请求回源,其余进入等待;proxy_cache_lock_timeout 就是这个“等待时间”的上限。
合理取值要基于后端真实响应能力
不能拍脑袋设,得看后端 P95 响应时间(含网络、序列化、DB 查询等全链路):
- 后端 P95 ≤ 300ms → 设为 1s~1.5s(留出余量)
- 后端 P95 在 1.2~2s → 推荐 3s
- 后端 P95 达到 4~6s(如聚合接口、报表类)→ 可设 6~8s,但需配套 stale 回退
- 绝对避免设为
0或100ms:会导致几乎全部请求立刻绕过锁,击穿上游 - 不建议超过
10s:用户端明显卡顿,移动端易重试,可能引发雪崩
示例:若压测发现后端 P95 是 2.4s,
proxy_cache_lock_timeout 3s是较稳妥的选择。
必须同步配置的三项关键项
单改 timeout 没用,以下三者缺一不可:
-
稳定 cache key
用显式定义剔除扰动参数,例如:proxy_cache_key "$scheme$host$uri";
避免因
?v=123、&ts=xxx或随机 header 导致 key 不一致,锁完全失效。 -
启用 stale 回退
让等待中的请求能返回旧缓存,消除用户侧延迟感:proxy_cache_use_stale updating error timeout http_500 http_502 http_503 http_504;
特别是
updating,表示“首个请求正在回源”,此时直接发旧内容。
FastAPI Flask Proxy下载FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
-
配合后台更新机制
开启异步刷新,避免锁释放后缓存立即陈旧:proxy_cache_background_update on;
这样即使用户拿到的是 stale 内容,Nginx 也会在后台悄悄更新缓存。
如何验证它真起作用
上线后别只看配置,盯住这三点:
-
响应头加
add_header X-Cache "$upstream_cache_status";,并发压测时观察是否出现:-
MISST(首个回源) -
UPDATING(其他请求正等新缓存,返回旧内容) -
HIT(几毫秒内返回,说明锁生效) - 大量
MISS(说明 key 不统一或 lock 未开启)
-
查后端 access log:同一 URI 的请求数是否在 MISS 阶段明显收敛(比如 100 并发只打出 1~2 个后端请求)
日志里搜
cache lock timeout:如果频繁出现,说明 timeout 设得太短,或后端确实不稳定
不复杂但容易忽略。










