ZoneAvoidanceRule 基于分区下的服务器的可用性选出可用分区列表,再从可用分区列表中随机选择一个分区,采用轮询的策略选择该分区的一个服务器。
属性 | 属性描述 | 默认值 |
---|---|---|
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、先获取可用分区集合。
可用分区选取的策略如下:
2、从可用分区集合中选择一个分区。
选择策略:累加每个可用分区中的服务器数量,基于这个总数生成一个随机数,找到对应服务器所在的分区。
3、从缓存中获取分区对应的负载均衡器,默认采用轮询的策略从服务器列表中选择一个服务器。
1.1 ZoneAvoidanceRule#create