proxy_cache_lock 仅在缓存 MISS 时串行化同 key 请求,依赖锁得准(统一 cache key)、锁得住(正确配置缓存区/启用缓存/开启 lock)、等得稳(合理设置 timeout)、退得快(use_stale 保底)、源头少(降低 MISS 频率)五要素协同生效。

proxy_cache_lock 不是“开关一开就防住击穿”的魔法配置,它只在缓存未命中(MISS)时,把同一 key 的并发请求串行化:首个去回源,其余排队等结果写入缓存后直接返回。真正起效,靠的是锁得准、等得稳、退得快、源头少这四个实操要点。
锁得准:所有请求必须落在同一个 cache key 上
key 不一致,等于没锁。默认 $scheme$proxy_host$request_uri 会把 /api/user?id=1 和 /api/user?id=2 当作两个 key,数万请求就变成数万个独立回源。
- 对固定路径热点接口(如商品详情页),显式收束 key:
proxy_cache_key "$scheme$host:/api/product"; - 更通用做法是剥离 query 参数:
proxy_cache_key "$scheme$host$uri";(丢掉$args) - 过滤前端加的随机参数(
?t=1718614290、?v=2.4.0)、用户身份头($http_x_user_id)、Cookie 等易变字段 - 配合
proxy_ignore_headers Set-Cookie Vary;,避免响应因含Set-Cookie被跳过缓存
锁得住:三要素缺一不可
没有缓存区、没启用缓存、location 里没开 lock,机制完全不触发。
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
- 在 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)要和后续引用一致;use_temp_path=off提升写入一致性 - 确保磁盘路径存在且 Nginx 进程可读写:
mkdir -p /var/cache/nginx/proxy_cache && chown www:www /var/cache/nginx/proxy_cache - 在目标 location 中必须启用缓存:
proxy_cache my_cache;
没这句,就没有 MISS,lock 就是摆设 - 在同一 location 中开启锁:
proxy_cache_lock on;<br>proxy_cache_lock_timeout 5s;
建议设为 3–8 秒:太短易放弃,太长用户卡顿
等不起时有退路:stale 是保命配置
首个请求若超时、报错或慢得离谱,不能让其余请求干等或全部穿透。
- 允许返回旧缓存(即使已过期):
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; - 搭配后台静默更新(可选):
proxy_cache_background_update on; - 对空响应也缓存,防穿透:
proxy_cache_valid 404 10s;
源头减压:减少 MISS 次数才是治本
锁只是缓解手段,降低 MISS 频率才能从根上减轻压力。
- 给热点响应设合理有效期:
proxy_cache_valid 200 302 30s;(API)或数小时(静态资源) - 避免被绕过:检查是否误配了
proxy_no_cache、proxy_cache_bypass,或响应头含Cache-Control: no-cache - 验证是否生效:加响应头
add_header X-Cache-Status $upstream_cache_status;,用curl -I观察首次为MISS、后续并发为HIT或LOCKING

















