max_fails通过滑动失败计数与fail_timeout配合实现节点软性退出:连续失败达阈值后临时标记为down,超时自动恢复,期间权重失效,恢复后原有权重立即生效。

加权轮询本身只决定健康节点之间的流量比例,max_fails 不改变这个比例逻辑,而是通过失败计数机制实现节点的临时隔离——这才是它真正起作用的方式。
max_fails 怎么让节点“软性退出”
它不是一出错就拉黑,而是在 fail_timeout 时间窗口内,对连续失败次数做动态累计。只要达到设定的 max_fails 值,该 server 就被临时标记为 down,Nginx 调度时会跳过它,继续按剩余健康节点的权重分发请求。
- 失败计数是滑动式的:每次失败都重置倒计时起点,fail_timeout 内的新失败会累加,中间成功不归零
- 节点标记为 down 后,fail_timeout 时间一到自动恢复为 up,无需 reload 配置
- 权重(weight)只在节点处于 up 状态时生效;down 期间权重失效,恢复后原有权重立即回归
配置必须写在每个 server 行上
不能只写在 upstream 块顶层,否则不生效。典型写法如下:
upstream app_cluster {
server 192.168.1.10:8080 weight=5 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 weight=2 max_fails=3 fail_timeout=30s;
server 192.168.1.12:8080 weight=3 max_fails=3 fail_timeout=30s;
}
- 正常时按 5:2:3 比例分发
- 若第一台连续失败 3 次,接下来 30 秒内被跳过
- 此时剩余两台仍按 2:3 比例承接全部流量,总负载自动重平衡
- 30 秒后,第一台自动回归,weight=5 重新起效
配合 proxy_next_upstream 实现请求级容错
仅靠 max_fails 只能避免后续请求打过去,当前请求已失败。要让单次请求也“换人重试”,需启用:
location / {
proxy_pass http://app_cluster;
proxy_next_upstream error timeout http_502 http_503 http_504;
}
- 当请求发给刚变 down 的节点(或尚未被标记但实际不可用的节点)时,Nginx 捕获错误并立刻转向下一个可用节点重试
- 用户无感知,后端故障被静默消化,相当于在单个请求粒度完成软隔离
别忘了基础健康检查配套
所有节点都应返回一致的健康接口(如 /health),并在 location 中补充:
proxy_next_upstream error timeout http_500;
- max_fails 默认值是 1,fail_timeout 默认是 10s,过于敏感,建议显式设为 3 和 30s
- 低配测试机可收紧策略:max_fails=2、fail_timeout=15s,更快识别异常
- 检查 error.log 是否有 “upstream server temporarily disabled” 记录,这是 max_fails 生效的直接证据


















