proxy_cache_lock 仅对缓存未命中请求有效,静态资源应由 Nginx 直接服务而非代理回源;需检查 location 是否误配 proxy_pass 处理静态后缀,正确做法是用 try_files 或 root 直接响应,并通过响应头和压测验证锁行为。

proxy_cache_lock 不能单独防止静态资源回源压垮后端,它只对「缓存未命中」的请求起作用;而静态资源本身通常应由 Nginx 直接服务,根本不需要回源。所以问题核心在于:你是否误将静态资源交给了后端处理?正确做法是让 Nginx 拦截并直接响应静态文件,而非转发给 upstream。
先确认静态资源是否真走代理
如果静态资源(如 .js、.css、.png)被配置了 proxy_pass,那它们就不是“静态资源服务”,而是反向代理请求——此时才可能触发 cache miss 和回源压力。必须先剥离这类误配:
- 检查 location 块是否用正则匹配了静态后缀却仍写了
proxy_pass,例如:location ~* \.(js|css|png|jpg)$ { proxy_pass http://backend; }→ 这是典型错误,应改为try_files $uri =404;或直接 root + sendfile - 确保静态资源路径不落入任何
proxy_pass范围,比如把静态资源放在/static/下,并用独立 location 显式处理 - 用
curl -I http://your.site/style.css查看响应头中的X-Proxy-By或Server,确认是否由 Nginx 直接返回(状态码 200 + 无上游 header)
只有代理型静态请求才需要 proxy_cache_lock
极少数场景下,静态资源需动态生成或鉴权(如带签名的临时图片链接、权限控制的 PDF),这时才走后端,也才需要缓存保护。此时启用 lock 才有意义:
阿里百炼大模型平台多人共享账号用量统计代理服务。解决公司共用账号时无法区分个人用量的问题。适用场景:1)部署用量统计代理;2)统计多人Token用量和调用次数;3)管理大模型API调用配额。
- 在对应 location 中启用缓存区和锁:
proxy_cache my_cache;<br>proxy_cache_lock on;<br>proxy_cache_lock_timeout 5s;
- 强制统一缓存 key,剔除干扰字段:
proxy_cache_key "$scheme$host$request_uri";(忽略 $args、$cookie、$http_ 等) - 禁止后端干扰缓存决策:
proxy_ignore_headers Cache-Control Expires Set-Cookie;(避免后端响应头禁用缓存)
搭配 stale 回退与长缓存有效期更关键
lock 只能减少首次并发回源数量,但无法解决 lock 持有者失败或超时的问题。必须叠加容错策略:
- 允许返回过期缓存应对异常:
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; - 为静态类响应设置较长有效时间:
proxy_cache_valid 200 302 1h;(比默认 10 分钟更抗抖动) - 配合
proxy_cache_background_update on;,让过期后首个请求异步刷新,其余继续用旧缓存
验证 lock 是否真实生效
别依赖配置存在就认为有效,必须观测行为:
- 添加调试头:
add_header X-Cache-Status $upstream_cache_status; - 并发请求同一 URL(如 ab -n 20 -c 10),观察响应头:
• 第一个应为X-Cache-Status: MISS
• 后续若干个应为X-Cache-Status: HIT(说明锁成功复用)
• 若全是 MISS,说明 key 不一致或配置未加载 - 查后端 access log:开启 lock 后,同一 key 的并发请求应只产生 1 条后端访问记录

















