proxy_cache_lock 防雪崩需组合配置:必须定义 keys_zone 并启用 proxy_cache;统一 proxy_cache_key 剔除动态参数;设 proxy_cache_lock_timeout 3–8s 及 use_stale updating 应对回源;通过 X-Cache-Status 和压测验证锁生效。

proxy_cache_lock 本身不防雪崩,它只在“同一缓存 key 瞬时未命中”时限制首个请求回源,其余等待——但若配置不当或缺少配套策略,它既压不住流量,也救不了后端。真正防范突发流量回源爆库,靠的是锁 + 缓存稳态 + 容错退路的组合拳。
必须先搭好缓存基础,否则 lock 形同虚设
lock 不是开关,而是依赖完整缓存上下文才能激活的机制:
- 在 http 块中定义缓存区:proxy_cache_path /var/cache/nginx/proxy_cache levels=1:2 keys_zone=my_cache:512m inactive=3h use_temp_path=off; —— keys_zone 名称(如 my_cache)后续会被引用,内存大小按每 1MB 支持约 8000 个 key 估算
- 目标 location 中必须启用缓存:proxy_cache my_cache; —— 没这句,Nginx 根本不进入缓存流程,MISS 都不会发生,lock 自然不触发
- 确保磁盘路径存在且 Nginx 进程有读写权限(注意 SELinux、umask 或容器挂载限制)
让锁真正“锁得住”:统一 key 是前提
锁按 cache key 绑定,key 不一致 = 多把锁并行 = 白配:
⚠️ 已弃用 — 该技能已拆分为两个独立技能,以提升模块化程度:**webchat-https-proxy**(HTTPS/WSS 反向代理)和 **webchat-voi...**
- 默认 key 含 $args,/api/order?id=1001 和 /api/order?id=1002 就是两个独立 key,各自回源
- 对热点接口(如商品详情、首页轮播),显式简化 key:proxy_cache_key "$scheme$host:/api/product";
- 更稳妥做法是剔除全部 query 参数:proxy_cache_key "$scheme$host$request_uri";
- 务必排除干扰项:不带 $cookie、$http_x_trace_id、?t=时间戳等动态字段,否则 key 总在变,锁永远打滑
不卡用户、也不压垮后端:timeout 与 stale 必须协同
lock 只控制谁先去,timeout 和 stale 才决定系统能不能扛住:
- proxy_cache_lock_timeout 5s; —— 推荐 3–8 秒。设为后端 P95 响应时间的 1.2–1.5 倍(例如 P95 是 2.4s,就设 3s);太短(1s)→ 大量请求超时并发回源;太长(15s)→ 用户明显卡顿
- proxy_cache_use_stale error timeout updating http_500–504; —— 关键在 updating:首个请求正在回源时,后续请求可直接返回旧缓存(哪怕已过期),彻底绕过等待
- proxy_cache_valid 200 302 30s; —— 对 API 接口延长有效时间,从源头减少 MISS;静态资源可设为 1h+
- 搭配 proxy_cache_background_update on;,让首个请求写完缓存后,后台静默刷新,不影响后续体验
验证是否真起作用,别信配置信日志
配置完不验证,等于没配:
- 在 location 中加响应头:add_header X-Cache-Status $upstream_cache_status;
- 用 ab 或 wrk 并发压测同一 URL(如 ab -n 100 -c 50 http://a.com/api/product)
- 观察响应头:首次请求为 MISS,紧随其后的大量请求应为 HIT(说明命中新写入缓存)或 STALE(说明走 stale 回退),极少连续出现多个 MISS
- 查 Nginx 日志中的 $upstream_cache_status 字段,确认 LOCKING / UPDATING 状态真实出现(Nginx 1.7.8+ 支持)










