聊聊Ribbon获取服务列表和负载均衡策略
聊聊Ribbon获取服务列表和负载均衡策略
在使用负载均衡器选取服务的时候是从所有的服务列表中获取的,那么服务列表是从哪里来的呢?
服务列表的获取
RibbonClientConfiguration中定义了ZoneAwareLoadBalancer负载均衡器,并使用了ServerList对象
我们看负载均衡器ZoneAwareLoadBalancer的构造方法,它的构造方法直接调用父类DynamicServerListLoadBalancer的构造方法,构造方法中有个restOfInit()方法:
重要的两步:
enableAndInitLearnNewServersFeature();
updateListOfServers();
我们看一下DynamicServerListLoadBalancer的enableAndInitLearnNewServersFeature()方法
serverListUpdater.start(updateAction);
我们看下updateAction这个成员遍历的定义:
protected final ServerListUpdater.UpdateAction updateAction = new ServerListUpdater.UpdateAction() {
@Override
public void doUpdate() {
updateListOfServers();
}
};
而start()中定义了定时线程,每隔一段时间调用了updateAction.doUpdate()来从Eureka或Nacos中读取服务列表保存到Ribbon本地缓存中
scheduledFuture = getRefreshExecutor().scheduleWithFixedDelay(
wrapperRunnable,
initialDelayMs,
refreshIntervalMs,
TimeUnit.MILLISECONDS
);
所以本质还是通过updateListOfServers来获取到服务列表的
说完这个服务列表的获取之后呢,我们在看两个常用的负载均衡器:RoundRobinRule和RandomRule
负载均衡器
RoundRobinRule 类重写choose()方法:
RoundRobinRule 轮询默认超过10次获取到空的服务,就返回空
RandomRule 随机如果选择的是空的话,就会一直进行循环,直到选择到可用的服务
Random rand;
public RandomRule() {
rand = new Random();
}
public Server choose(ILoadBalancer lb, Object key) {
....
int index = rand.nextInt(serverCount);
server = upList.get(index);
.....
}
使用随机数选择索引值,然后从服务列表中选择服务
ZoneAvoidanceRule 这个就不用过多介绍了,是默认的策略,它继承PredicateBasedRule类,轮询,会过滤掉不符合Zone的节点
RetryRule 重试策略,如果选择为空或不可用就在5000ms内不停的重试
AvailabilityFilteringRule是可用过滤策略,它先轮询选择一个,然后判断是否超时,是否连接数超过限制,都没有问题后进行返回
BestAvailableRule 最小连接数策略,也就是选取连接数最小的那个服务,连接数信息是在LoadBalancerStats中保存的
总结
这篇文章主要讲了Ribbon是怎么获取服务列表和负载均衡策略有哪些,获取服务列表本质是通过一个定时线程每隔一段时间从远程获取到列表信息并保存到ribbon自身缓存中,负载均衡器有很多,默认是ZoneAvoidanceRule,我们可以选择合适的负载均衡器,也可以自定义负载均衡器
- 点赞
- 收藏
- 关注作者
评论(0)