Ribbon架构篇 - ZoneAvoidanceRule

本文深入探讨了Ribbon的ZoneAvoidanceRule,它基于分区的服务器可用性选择可用分区,然后从这些分区中随机选择并使用轮询策略选择服务器。内容涵盖了ZoneAwareLoadBalancer的工作流程,包括获取可用分区、选择分区、服务器负载计算以及断路器策略等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

ZoneAvoidanceRule 基于分区下的服务器的可用性选出可用分区列表,再从可用分区列表中随机选择一个分区,采用轮询的策略选择该分区的一个服务器。

ZoneAwareLoadBalancer

属性 属性描述 默认值
ZoneAwareNIWSDiscoveryLoadBalancer.enabled 是否开启ZoneAwareLoadBalancer true
niws.loadbalancer.default.connectionFailureCountThreshold 连接失败的数量的阈值 3
niws.loadbalancer.default.circuitTripTimeoutFactorSeconds 断路器打开的超时时间因子 10
niws.loadbalancer.default.circuitTripMaxTimeoutSeconds 断路器打开的超时时间阈值 30
ZoneAwareNIWSDiscoveryLoadBalancer.default.triggeringLoadPerServerThreshold 每台服务器的负载的阈值 0.2
niws.loadbalancer.serverStats.activeRequestsCount.effectiveWindowSeconds 活跃请求数发生变化的超时时间 600
ZoneAwareNIWSDiscoveryLoadBalancer.default.avoidZoneWithBlackoutPercetage 服务器故障率阈值 0.99999
@Override
public Server chooseServer(Object key) {
   
		// 如果没有开启 ZoneAwareLoadBalancer 或者 LoadBalancerStats记录的可用分区数 <= 1
		// 则执行 BaseLoadBalancer#chooseServer(...) 的逻辑
    if (!ENABLED.get() || getLoadBalancerStats().getAvailableZones().size() <= 1) {
   
        logger.debug("Zone aware logic disabled or there is only one zone");
        return super.chooseServer(key);
    }

    Server server = null;
    try {
   
        LoadBalancerStats lbStats = getLoadBalancerStats();
      	// 创建分区快照
        Map<String, ZoneSnapshot> zoneSnapshot = ZoneAvoidanceRule.createSnapshot(lbStats);
        logger.debug("Zone snapshots: {}", zoneSnapshot);
        if (triggeringLoad == null) {
   
            triggeringLoad = DynamicPropertyFactory.getInstance().getDoubleProperty(
                    "ZoneAwareNIWSDiscoveryLoadBalancer." + this.getName() + ".triggeringLoadPerServerThreshold", 0.2d);
        }

        if (triggeringBlackoutPercentage == null) {
   
            triggeringBlackoutPercentage = DynamicPropertyFactory.getInstance().getDoubleProperty(
                    "ZoneAwareNIWSDiscoveryLoadBalancer." + this.getName() + ".avoidZoneWithBlackoutPercetage", 0.99999d);
        }
      	// 获取可用的分区集合
        Set<String> availableZones = ZoneAvoidanceRule.getAvailableZones(zoneSnapshot, triggeringLoad.get(), triggeringBlackoutPercentage.get());
        logger.debug("Available zones: {}", availableZones);
        if (availableZones != null &&  availableZones.size() < zoneSnapshot.keySet().size()) {
   
          	// 从可用的分区集合中随机选择一个分区
            String zone = ZoneAvoidanceRule.randomChooseZone(zoneSnapshot, availableZones);
            logger.debug("Zone chosen: {}", zone);
            if (zone != null) {
   
              	// 从缓存中获取分区对应的负载均衡器,初始会创建 BaseLoadBalancer 负载均衡器
                BaseLoadBalancer zoneLoadBalancer = getLoadBalancer(zone);
                // 默认采用轮询的策略从服务器列表中选择一个服务器
                server = zoneLoadBalancer.chooseServer(key);
            }
        }
    } catch (Exception e) {
   
        logger.error("Error choosing server using zone aware logic for load balancer={}", name, e);
    }
    if (server != null) {
   
        return server;
    } else {
   
        logger.debug("Zone avoidance logic is not invoked.");
        return super.chooseServer(key);
    }
}

1、先获取可用分区集合。

可用分区选取的策略如下:

  • 如果只有一个分区,则选择该分区作为可用分区。
  • 如果有多个分区,满足分区下的服务器数量大于0、服务器故障率小于阈值的、再随机排除一个服务器的负载大于平均负载的分区,作为可用分区,添加到可用分区集合中。

2、从可用分区集合中选择一个分区。

选择策略:累加每个可用分区中的服务器数量,基于这个总数生成一个随机数,找到对应服务器所在的分区。

3、从缓存中获取分区对应的负载均衡器,默认采用轮询的策略从服务器列表中选择一个服务器。


1.1 ZoneAvoidanceRule#create

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值