proxy_cache_lock不能单独解决缓存击穿,必须配合proxy_cache_path定义、proxy_cache引用、proxy_cache_key统一、proxy_cache_lock_timeout设置及proxy_cache_use_stale策略协同生效。

proxy_cache_lock 本身不能“完美解决”缓存击穿,它只是缓解高并发下缓存未命中时的源站冲击,必须配合严谨配置与策略协同才能真正起效。
基础配置必须全部到位
缺一不可,否则 lock 完全不生效:
- 在 http 块中定义 proxy_cache_path,含 keys_zone(如 my_cache:10m),这是锁的共享内存载体
- 在 location 块中启用缓存:proxy_cache my_cache
- 在同一 location 中开启锁:proxy_cache_lock on
- 确保请求真实触发 cache miss——若响应头含 Cache-Control: no-cache、匹配了 proxy_no_cache 规则,或被 Nginx 判定为 bypass,则 lock 不介入
锁只对完全一致的缓存 key 生效
key 不一致 = 锁失效 = 并发回源照旧发生。常见原因包括:
- query 参数未统一处理:默认 $request_uri 包含 ?id=1 和 ?id=2 是两个 key;应改用 proxy_cache_key "$scheme$host$request_uri" 或更严格地剔除参数(如 "$host:/api/user")
- Cookie 或 header 差异干扰:登录用户带 session cookie,游客不带,默认 key 就不同;需配合 proxy_ignore_headers Set-Cookie 并在 key 中剥离无关字段
- 前端加随机参数:如 ?t=1713086520 或 ?v=2.3.1,必须显式忽略,否则每个请求都是独立 key
关键增强配置组合
单靠 lock 无法应对高并发 MISS 场景,必须三者并用:
- 设合理超时:proxy_cache_lock_timeout 推荐 3–8 秒。太短,等待请求放弃锁直接回源;太长,用户明显卡顿
- 启用 stale 回退:proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504。当首个请求回源失败或超时,后续请求可立即返回旧缓存,避免全部堆积或降级失败
- 延长热点缓存有效期:proxy_cache_valid 200 302 可设为 30s(API)或数小时(静态资源)。MISS 越少,lock 竞争越弱
验证是否真正生效
别依赖猜测,用实际观测确认:
- 在 location 中添加:add_header X-Cache-Status $upstream_cache_status
- 用 curl -I 查看响应头:首次请求应为 MISS,紧随其后的并发请求应出现 HIT(说明锁成功阻塞并复用结果)或仍为 MISS(说明 key 不一致或配置未生效)
- 查后端访问日志:用 ab -n 20 -c 10 并发压测同一 URL,开启 lock 后后端应仅记录 1 条访问,而非 10 条











