缓存失效会放大流量冲击,需通过被动健康检查(max_fails/fail_timeout、proxy_next_upstream、收紧超时)、主动探测(nginx_upstream_check_module)、缓存锁协同(proxy_cache_lock+timeout)、DNS动态解析(resolver+变量)四层机制提前防控节点故障。

缓存失效本身不直接导致节点故障,但它会把原本被缓存挡住的流量瞬间释放到后端,暴露出节点的真实健康状况。这时候如果节点已经异常,又缺乏及时感知和隔离机制,502、超时、雪崩就很容易发生。关键不是“等缓存失效了再处理”,而是让健康检查在缓存失效前就起作用,失效后能快速响应。
用被动健康检查守住第一道防线
这是开源 Nginx 最可靠、无需额外模块的方式,必须配齐三个要素:
-
upstream 中每个 server 明确设置 max_fails 和 fail_timeout:比如
server 10.0.1.10:8080 max_fails=2 fail_timeout=10s;,表示 10 秒内失败 2 次即标记为 down -
location 中启用 proxy_next_upstream:至少包含
error timeout http_502,让 Nginx 知道哪些响应要计入失败计数 -
收紧超时参数:
proxy_read_timeout 3s;+proxy_connect_timeout 2s;,避免单个请求卡死拖慢整个队列
这样,当缓存失效引发并发回源时,哪怕某个节点只是变慢(RT 升到 4s),也会因超时被快速踢出,后续请求自动流向健康节点。
用主动探测提前发现隐患节点
被动检查靠“出事才报警”,而缓存失效是典型压力放大器。建议引入 nginx_upstream_check_module 做主动心跳:
- 在 upstream 块里加
check interval=3s rise=2 fall=3 type=http; - 搭配
check_http_send "HEAD /health HTTP/1.0\r\n\r\n";和check_http_expect_alive http_2xx; - 探活路径必须轻量、不依赖缓存、不走业务逻辑链路(如数据库)
它能在缓存还没失效、流量还没压上来之前,就把响应迟钝或假死的节点提前摘除,把风险拦截在爆发前。
缓存锁与健康检查协同防串行阻塞
启用 proxy_cache_lock on; 后,多个 MISS 请求会排队等待首个回源结果。若首个请求打到一个已卡住但尚未被标记为 down 的节点,后面所有请求都会干等——直到 proxy_cache_lock_timeout 超时。
- 把
proxy_cache_lock_timeout设为略高于proxy_read_timeout(例如 3s),避免无谓长等 - 确保
proxy_next_upstream包含timeout,这样锁等待期间一旦上游超时,Nginx 就会换节点重试,而不是死守一个坏节点 - 配合
proxy_cache_lock_age控制补位频率,防止多个节点接连被误伤
结合 DNS 变更做动态兜底
如果后端用的是域名(如 api.service.cluster),IP 变更后 Nginx 默认不会重解析,旧 IP 上的节点即使已下线,仍可能持续收请求并返回 502。
- 改用变量 + resolver 方式:
set $backend "api.service.cluster"; proxy_pass http://$backend;,并在 location 内配置resolver 10.0.0.2 valid=10s; - resolver 必须和变量同级生效,不能只写在 http 块顶层
- 这样每次请求都可能触发新解析,配合健康检查,就能在 IP 更新后几秒内完成节点切换


















