fail_timeout 通过设定故障节点的“冷静期”来缓解雪崩风险:它使节点被标记为 down 后静默等待指定时长,再由真实请求单次试探,避免频繁试探加重后端负担;需与 max_fails 协同定义失败判定窗口,并配合 proxy_read_timeout 和 proxy_next_upstream 配置确保机制生效,叠加主动健康检查可提升可靠性。

fail_timeout 本身不直接“规避雪崩”,但它作为 upstream 故障管理的时间锚点,能显著降低因误判、过早恢复或反复试探引发的连锁压力。关键在于把它用作一个可控的冷却与观察窗口,而非被动等待。
用 fail_timeout 控制故障节点的“冷静期”
节点被标记为 down 后,并不会自动重连或定时探活;它会安静等待 exactly fail_timeout 秒,之后才靠下一个真实请求去单次试探。这个静默期就是防止雪崩的第一道缓冲:
- 设太短(如 5s):后端可能还在 GC、连接重建或慢查询中,Nginx 就已发试探请求,失败后继续 down → 形成“试探-失败-再等-再试探”的恶性循环,徒增后端负担
- 设太长(如 120s):节点实际已恢复,却仍被隔离两分钟,流量长期压在其余节点上,易导致剩余节点过载甚至级联崩溃
- 合理值应略大于后端典型恢复时间:例如 PHP-FPM 实例重启+预热约 8–12s,可设 fail_timeout=15s;Java 服务 GC 后稳定需 20–30s,可设 40s
配合 max_fails 构建滑动失败判定窗
fail_timeout 和 max_fails 必须协同使用,共同定义“多快算真坏”:
- 高频轻量接口(如心跳、配置拉取):max_fails=1, fail_timeout=10s → 单次失败即隔离,避免错误状态扩散
- 常规 API(QPS 数百,RT 150ms):max_fails=3, fail_timeout=30s → 容忍一次 GC 暂停或瞬时丢包,不因抖动误剔
- 慢响应服务(报表导出、大文件上传):max_fails=2, fail_timeout=60s → 避免一次正常耗时 45s 的请求被计入失败,导致健康节点被误摘
必须同步约束 proxy_read_timeout 和 proxy_next_upstream
只调 fail_timeout 没用,以下两项不匹配会导致机制完全失效:
- proxy_read_timeout 必须小于 fail_timeout:例如 fail_timeout=30s,proxy_read_timeout 应设为 10–20s。否则请求卡在读阶段超时,无法及时触发失败计数,节点该 down 不 down
- proxy_next_upstream 必须显式包含业务错误码:默认只统计 connect refused 和 timeout;若后端返回 502/503/504,需手动加入,如:proxy_next_upstream error timeout http_502 http_503 http_504
叠加主动健康检查形成双保险
fail_timeout + max_fails 是被动机制(靠请求失败触发),容易滞后。建议额外配置主动健康检查,提前发现隐患:
- 在 upstream 块中加:health_check interval=5 fails=2 passes=2;
- 检查路径应真实反映业务可用性,例如 check_http_expect_alive 2xx 3xx,避免用空 /health 接口
- 主动检查与被动摘除并行:即使某节点尚未触发 max_fails,只要健康检查连续失败 2 次,也会立即隔离










