小知识,大挑战!本文正在参与「程序员必备小知识」创作活动
13负载均衡器之ZoneAwareLoadBalancer
ZoneAwareLoadBalancer负载均衡器是对DynamicServerListLoadBalancer的继承,DynamicServerListLoadBalancer没有重写选择具体服务实例的chooseServer方法,依然采用BaseLoadBalancer中实现的方法,使用RoundRobinRule规则,以线性轮询的方式来选择调用的服务实例。
ZoneAwareLoadBalancer重写了选择具体服务实例的chooseServer方法
@Override
public Server chooseServer(Object key) {
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 zoneLoadBalancer = getLoadBalancer(zone);
server = zoneLoadBalancer.chooseServer(key);
}
}
} catch (Throwable e) {
logger.error("Unexpected exception when choosing server using zone aware logic", e);
}
if (server != null) {
return server;
} else {
logger.debug("Zone avoidance logic is not invoked.");
return super.chooseServer(key);
}
}
- 调用ZoneAvoidanceRule.createSnapshot,为当前负载均衡器中所有的Zone区域分别创建快照
- 调用ZoneAvoidanceRule.getAvailableZones(zoneSnapshot, triggeringLoad.get(), triggeringBlackoutPercentage.get());获取可用的的Zone区域集合
- 当获得可用Zone区域不为空,并且个数小于Zone区域总数,就随机选择一个Zone区域
- 在确定某个Zone区域后,获取对应Zone区域的负载均衡器,调用chooseServer方法来选择具体的服务实例,这里使用ZoneAvoidanceRule来挑选具体的服务实例。
这就是负载均衡器之ZoneAwareLoadBalancer的具体逻辑和实现,还有很多细节没有一一展开,以后的文章中我们再细说细聊。