fail_timeout定义节点被标记为down后的静默观察期,与max_fails构成滑动时间窗口机制,到期仅靠首个业务请求试探恢复;需按后端平均恢复时间设定(如Web服务30–60s),并同步收紧proxy_read_timeout等配套超时,否则机制失效。

fail_timeout 本身不控制重试频率,而是定义节点被标记为不可用后的“静默观察期”。它和 max_fails 配合,构成一个滑动时间窗口机制——这个窗口才是规避重试雪崩的关键支点。
理解 fail_timeout 的真实作用
当某 upstream 节点在 fail_timeout 秒内累计失败 ≥ max_fails 次,Nginx 就将其标记为 down,并在接下来的 fail_timeout 秒内完全跳过它,不发任何请求。到期后,仅靠第一个真实业务请求试探恢复:成功则重新加入轮询;失败则重置计时。
它不是周期性探测,也不主动发心跳。真正的“规避雪崩”,靠的是这个静默期把无效重试彻底拦住,不让故障节点持续吸走流量。
设太小会引发震荡,设太大会拖慢恢复
- fail_timeout=3s:节点刚恢复就遇到一次慢请求或 GC 暂停,试探失败,立刻再次下线,形成“上线→失败→下线→再上线”的高频震荡
- fail_timeout=120s:后端已重启完成,但 Nginx 还要等整整两分钟才发第一次试探请求,期间所有流量都压在其他节点上,可能造成二次过载
- 推荐值按后端平均恢复时间设定:Redis 崩溃重启通常 5–10 秒,可设为 10–15s;Web 应用常见 20–45 秒,建议 30–60s
必须同步收紧超时配套,否则 fail_timeout 形同虚设
如果 proxy_read_timeout 大于 fail_timeout,试探请求会在读阶段卡满 timeout,导致整个 fail_timeout 周期被“无效占用”,无法及时触发下一次恢复尝试。
- fail_timeout=10s 时,proxy_read_timeout 应 ≤5s,proxy_connect_timeout ≤2s
- 启用 proxy_next_upstream error timeout(必选),确保连接失败和读超时都能计入失败统计
- 禁用 proxy_next_upstream http_502(除非明确需要),避免缓存服务崩溃返回 502 后反复重试其他节点,掩盖真实故障点
叠加主动健康检查,补足被动机制的滞后性
仅靠 fail_timeout + max_fails 是被动响应,恢复依赖真实请求驱动。对低延迟或强一致性要求高的场景,建议补充主动探活:
- 在 upstream 块中配置 health_check interval=3 fails=2 passes=2
- 检查路径需真实反映服务状态,例如 check_http_expect_alive 2xx 3xx,且 /health 接口必须执行实际连接检测(如 Redis::ping)
- 主动检查与 fail_timeout 双机制并行:主动发现提前隔离,被动机制兜底恢复

















