排查Nginx故障转移中max_fails过严导致“误杀”,需验证后端是否被错误标记为down,检查error_log中频繁连接失败报错、access_log中502/503及upstream_addr为none、stub_status显示fails反复达阈值后down又恢复,并对比fail_timeout与实际响应时间,模拟探测与压测验证,最后调高max_fails、延长fail_timeout、控制重试并启用slow_start。

排查 Nginx 故障转移中 max_fails 设置过严导致的“误杀”,核心是验证后端健康状态是否被错误标记为 down,同时确认失败判定逻辑与实际网络/应用行为不匹配。重点看日志、主动探测结果和 upstream 状态。
查 access_log 和 error_log 中的 upstream 相关记录
Nginx 不会直接记录“因 max_fails 达标而标记 down”,但会在 error_log 中频繁输出连接失败原因,在 access_log 中体现 502/503 状态码及 upstream 地址。开启详细日志后重点关注:
- error_log 中出现大量类似
connect() failed (111: Connection refused) while connecting to upstream或upstream timed out (110: Connection timed out) while connecting to upstream的报错,且集中在同一 server - 同一 backend server 在短时间内(短于 fail_timeout)连续触发多次失败日志,符合 max_fails 阈值
- access_log 中该 server 对应请求返回 502/503,且 upstream_addr 字段显示为
none或跳转到其他 backup server
用 stub_status 或第三方模块实时观察 upstream 状态
启用 ngx_http_stub_status_module(需编译时开启)或使用 nginx-module-vts 等增强监控模块,可直观看到每个 upstream server 的当前状态、fails 计数、down 标记及时长。例如:
- 访问
/status页面,发现某 server 的fails值在波动上升,且反复达到max_fails后变down,几秒后又恢复 —— 这是典型过严信号 - 对比
fail_timeout和实际业务响应时间:若fail_timeout=10s但后端偶发慢请求达 8s,而max_fails=1,则一次慢请求就触发摘除,明显不合理
模拟请求并验证失败判定条件是否合理
手动模拟 Nginx 对后端的探测行为(注意:Nginx 默认不主动探测,而是基于真实请求失败计数):
- 用
curl -I http://backend-ip:port/health检查后端健康接口是否稳定返回 200;若偶尔超时或返回非 200,就可能被计入失败 - 用
ab或wrk对 upstream 发起压测,观察 Nginx 日志中该 server 的 fails 是否异常增长 —— 若并发稍高就触发 max_fails,说明阈值偏低或后端抗抖动能力弱 - 检查是否启用了
proxy_next_upstream,若配置了error timeout http_500等,会扩大“失败”范围,间接加剧误杀
调整与验证建议
修改前先备份配置,每次只调一个参数并观察至少两个 fail_timeout 周期:
- 将
max_fails从默认 1 提高到 3 或 5(尤其对偶发延迟敏感的后端) - 适当延长
fail_timeout(如设为 30s),避免刚恢复就再次被误判 - 配合
proxy_next_upstream_tries控制重试次数,防止单次请求多次触发失败计数 - 对关键后端,可加
slow_start=30s,避免刚恢复就承接全量流量











