dubbo默认负载均衡以及权重算法源码阅读

 
dubbo 提供的集中负载均衡策略
 
 
dubbo 默认使用 RandomLoadBalance
 
图 1
 
具体看select方法 返回具体的 invoker对象,
 
 
图2
 
select 方法
sticky 粘性?这里不太懂,大概是选中invoker后,每次都选同一个invoker,  这里不纠结了,暂时跳过, 直接看 deselect方法
 
图3
 
deselect 方法,如果invokers size是1,直接返回,如果两个轮询 ,这里有个不太明白的地方  selected 是在每次调用中初始化的,如何知道上次选择了哪个invoker?  
 
经过debug发现这个轮询是指在失败的情况下,两个invoker交替使用 ,dubbo默认使用的是FailoverClusterInvoker(When invoke fails, log the initial error and retry other invokers (retry n times, which means at most n different invokers will be invoked), 默认重试2+1次。所以这个selected list放的是一次远程调用中已经调用过的invoker,当selected list 不为空,说明肯定存在调用失败的invoker
在图二中可以发现,当 i>0 (首次调用失败之后) 会调用checkWhetherDestroyed方法
 
图4
 
继续看 loadbalance.select方法
图5
 
具体实现在子类实现的 doSelect方法中,这里使用的是RandomLoadBalance
 
  
 
图6
 
这里循环计算每个invoker的weight, 如果weight相同就随机返回一个,不同的话 随机获取一个[0, totalWeight)之间的数, offset = offset - weight,如果 offset 小于0,则选中,
 
很明显weight大的更容易让offset的值小于0,  
举个例子 有 4个invoker 权重分别为(1,2, 3, 4),totalWeight = 10, 假如 offset = 6,  6 - 1 = 5, 5大于0,继续 5 - 2 = 3 大于0,3 - 3 = 0, 0 - 4 小于0 ,所以选择权重为4的 invoker, 这里可以发现只要offset >= 6 则选择权重为4的invoker, 正好是40%。
 
我们看下getWeight方法
 
图7
 
默认weight是100,这里有个根据预热时间来计算权重的算法,先获取provider端的启动时间,在通过当前时间减去provider端启动的时间得到已经启动的时间 uptime
,获取配置warmup时长,如果uptime 小于 warmup,说明还在预热阶段,需要相应的减少权重。算法见上图中 33行 calculateWarmupWeight, 获取启动 uptime时长对应的权重
weight / warmup 得到单位时间的权重,再乘以已经启动的时长uptime 得到 uptime 时长对应的权重。 
 
预热这里老版本之前取的 consumer端的启动时间是没有预热效果的 
  
 
总体流程
 
AbstractClusterInvoker invoke -> doInvoke
    
FailoverClusterInvoker doInvoke -> select
 
AbstractClusterInvoker select -> doSelect
 
AbstractClusterInvoker doSelect -> loadbalance select
 
 
 

猜你喜欢

转载自www.cnblogs.com/xiaoyukid/p/9943124.html