一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

Nginx 中 fastcgi_cache_lock 阻止请求重复回源

时间:2026-07-01 10:55:04 编辑:袖梨 来源:一聚教程网

开启 fastcgi_cache_lock on 后,Nginx 通过串行化回源避免雪崩:首个请求获锁并回源,其余请求在用户态阻塞最多5秒等待缓存写入后统一返回;超时则各自回源。

开启 fastcgi_cache_lock on 后,Nginx 能确保同一未缓存 URL 的多个并发请求中,只有一个穿透到 PHP-FPM,其余请求在 Nginx 层等待结果写入缓存后直接返回——这本质上不是“防重复”,而是“串行化回源”,从而避免大量请求同时打到后端造成雪崩。

它怎么做到只放行一个请求?

当多个请求命中同一个 cache key 且当前无有效缓存时:

  • 首个请求获得“锁”,正常发往后端执行(如 PHP 处理)
  • 其余请求不立即回源,也不失败,而是在 Nginx 用户态阻塞等待
  • 等待上限固定为 5 秒(硬编码,不可配置)
  • 首个请求成功写入缓存后,所有等待请求统一从缓存读取并返回
  • 若超时未完成,等待请求自动放弃锁,各自回源(此时可能再次并发)

关键前提:缓存键必须一致

如果请求 URL 或 header 导致 cache key 不同,锁就形同虚设。常见问题包括:

  • URL 带随机参数(如 ?t=123456)→ 每次 key 都不同
  • 响应含 Set-CookieCache-Control: no-cache → Nginx 默认不缓存,导致反复 miss
  • 未忽略干扰头:fastcgi_ignore_headers Set-Cookie Cache-Control; 必须显式配置
  • 推荐 key 写法:fastcgi_cache_key "$scheme$host$request_uri";(不含 $args 或 cookie 相关变量)

必须配套的三项配置

单独开 lock 效果有限,需与以下参数协同:

  • fastcgi_read_timeout ≥ 后端最长合理耗时:例如 PHP 接口平均 8 秒,timeout 至少设为 10s;否则首个请求被 Nginx 中断,锁失效,后续请求全部回源
  • fastcgi_cache_valid 设置合理 TTL:避免大量缓存同时过期引发集中 miss;对高频页建议 10–30 分钟,并配合 inactive 控制清理节奏
  • fastcgi_cache_use_stale updating:允许在锁等待期间返回旧缓存内容,用户无感知延迟,后端压力进一步降低

什么情况下不该开 lock?

并非所有场景都适用:

  • 后端接口本身很慢(如导出、搜索聚合),且无法保证在 5 秒内完成 → 等待全超时,反而引发重试风暴
  • PHP-FPM worker 不足或数据库连接池饱和 → 首个请求卡住,拖垮整体响应
  • 业务要求强一致性(如秒杀下单页),不能接受旧缓存 → lock 仍会返回陈旧内容
  • 此时应关闭 lock,改用限流(limit_req)、降级(fastcgi_cache_use_stale error timeout)或异步预热

热门栏目