proxy_cache_lock仅能缓解高度重复的恶意请求引发的缓存击穿,需配合合理cache_key、lock_timeout和cache_valid等配置;对随机URL、POST请求或绕过Web层的攻击完全无效。

用 proxy_cache_lock 应对突发恶意流量,本质是借 Nginx 缓存层做“请求熔断”,但它不是万能盾,更不是数据库防火墙。它只在特定条件下起作用:攻击流量必须可被缓存、后端响应有明确缓存策略、且恶意请求高度重复(比如反复刷同一个动态接口)。若攻击者随机变换 URL、带时间戳参数或 User-Agent,proxy_cache_lock 会完全失效。
什么情况下 proxy_cache_lock 真的有用
它适合防御那种“看起来像正常访问、但频率极高且目标单一”的流量,例如:
- CC 攻击中反复 GET /api/check?token=abc 这类带固定参数的校验接口
- 爬虫或脚本高频访问静态化程度高的商品详情页(如 /item/12345)
- 第三方平台模拟用户批量查询订单状态,URL 规律性强、响应体稳定
关键配置要点不能漏
光开 proxy_cache_lock on 不够,必须配套以下设置才能真正压住回源压力:
-
缓存键要合理:用
proxy_cache_key剔除干扰参数(如时间戳、随机串),否则每个请求都算新 key,锁形同虚设 -
锁等待时间要可控:配合
proxy_cache_lock_timeout(建议 5–10 秒),避免大量请求卡在锁队列里拖垮 Nginx 自身 -
必须配缓存过期策略:
proxy_cache_valid 200 302 10s类规则不能省,否则缓存不生效,锁也无从谈起 -
后端需返回可缓存头:确保应用返回
Cache-Control: public, max-age=10或至少不带no-store
它防不住哪些攻击
遇到这些情况,proxy_cache_lock 基本不起作用,得换其他手段:
- 攻击者每请求都加唯一参数(如
?t=1716711123456),导致缓存 key 全不同 - 请求走 POST 方法且 body 随机,Nginx 默认不缓存 POST 响应
- 攻击直接打数据库连接池(如 Connection Flood),绕过 Web 层,Nginx 根本没机会介入
- CC 攻击伪造真实浏览器行为,触发 reCAPTCHA v3 低分拦截,但 HTTP 状态码仍是 200,Nginx 无法识别“静默失败”
比 lock 更实在的几招补位措施
单靠一个缓存锁守不住数据库,需要组合出拳:
-
前置限流:用
limit_req按 IP 或 UID 限制单位时间请求数,比等缓存锁更早掐断洪水 - 动静分离+CDN 卸载:把可静态化的页面推到 CDN,让恶意流量打在边缘节点,不碰源站
- 数据库连接池加固:调小最大连接数、缩短空闲超时、启用连接复用,防止 Connection Flood 耗尽资源
- 业务层快速熔断:在应用代码里对高频失败接口自动降级(如返回兜底 JSON),不依赖 Nginx











