proxy_cache_lock on 实现的是缓存 miss 时的请求串行化回源,而非缓存写入原子性;需同时满足 cache 区定义、location 启用缓存、锁开启及 key 统一三条件,并配合 stale updating 和 background_update 才能真正保障更新确定性。

proxy_cache_lock on 不是让缓存“原子更新”,而是让同一缓存 key 的首次未命中请求串行化回源——它不改变缓存写入本身是否原子,但能防止多个并发 MISS 请求同时打到后端,从而在逻辑层面保障“一次更新、多次复用”的原子性效果。
要让这个机制真正强化缓存更新的确定性和可控性,得从三个层面协同落地:锁的触发前提、锁的作用边界、以及锁失效时的兜底策略。
锁生效的前提必须全部满足
缺一不可,否则配置再全也形同虚设:
-
在
http块中定义缓存区,且带keys_zone(这是锁的共享内存基础):proxy_cache_path /var/cache/nginx/proxy_cache levels=1:2 keys_zone=my_cache:256m inactive=1h use_temp_path=off;
注意路径存在、Nginx 进程有读写权限;
use_temp_path=off避免临时文件拷贝,提升写入一致性。 -
在目标
location中明确启用缓存:proxy_cache my_cache;
没这句,Nginx 根本不进入缓存流程,
proxy_cache_lock就不会被触发。 -
同一
location内开启锁并设合理超时:
CPA Update - Secure CLI Proxy API Maintenance下载安全更新和维护 CLI Proxy API(CPA)部署与配置。用于 CPA 镜像升级、配置变更、认证目录兼容修复、上线验证与回滚。适用于用户提到“CPA 更新/升级/配置改了/容器重建/回滚”等场景。
proxy_cache_lock on; proxy_cache_lock_timeout 5s;
超时值建议略大于后端 P95 响应时间(比如后端平均耗时 3.8s,设为 5s),太短易放行多路回源,太长用户感知卡顿。
锁只对完全一致的 cache key 生效
key 不统一,等于没锁。常见导致 key 分裂的情况和应对方式:
默认
$request_uri包含查询参数 →/api/user?id=1和/api/user?id=2是两个 key
✅ 统一剥离参数:proxy_cache_key "$scheme$host$uri";前端加随机参数(如
?t=1716942840、?v=2.4.1)→ 每个请求都是新 key
✅ 强制收束:proxy_cache_key "$host:/api/user";Cookie 或
Authorization头不同 → 登录用户与游客生成不同 key
✅ 忽略干扰头:proxy_ignore_headers Set-Cookie Vary;,且不在 key 中引用$cookie_*或$http_authorization
锁等待期间必须有容错退路
光靠等锁风险高——首个请求可能失败、超时或卡住。必须搭配:
-
允许返回过期缓存(stale):
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
关键是
updating:当缓存已过期但后台正在刷新时,直接返回旧内容,用户无感,锁竞争大幅降低。 -
配合后台静默更新(可选但推荐):
proxy_cache_background_update on;
让“更新”动作在后台跑,不影响用户响应流;配合
stale updating,实现“秒开+零感知”。
不复杂但容易忽略










