Dubbo组件 — LoadBalance组件分析

本文深入剖析了Dubbo中的负载均衡组件,包括AbstractLoadBalance的select()和getWeight()方法,以及RandomLoadBalance、LeastActiveLoadBalance、RoundRobinLoadBalance和ConsistentHashLoadBalance的实现原理。详细介绍了随机加权、最小活跃数、轮询和一致性哈希负载均衡策略的工作流程和负载过程分析。
摘要由CSDN通过智能技术生成

目录

1.LoadBalance

2.AbstractLoadBalance

1.select()

2.getWeight()

3.RandomLoadBalance

4.LeastActiveLoadBalance

5.RoundRobinLoadBalance

1.WeightedRoundRobin

2.doSelect()

3.负载过程分析

6.ConsistentHashLoadBalance

1.算法思路

2.ConsistentHashSelector

3.doSelect()


1.LoadBalance

默认实现是RandomLoadBalance,对RegistryDirectory#list()出来的Invokers进行选择,然后发起访问

@SPI(RandomLoadBalance.NAME)
public interface LoadBalance {

   
    @Adaptive("loadbalance")
    <T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException;

}

2.AbstractLoadBalance

1.select()

public <T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) {
	if (CollectionUtils.isEmpty(invokers)) {
		return null;
	}
    
    // 如果只有一个 那不需要负载算法选择
	if (invokers.size() == 1) {
		return invokers.get(0);
	}
    
    // 模板方法 由子类实现
	return doSelect(invokers, url, invocation);
}

2.getWeight()

protected int getWeight(Invoker<?> invoker, Invocation invocation) {
    // 获取 sayHello.weight 或者 weight,默认权重都是100
	int weight = invoker.getUrl().getMethodParameter(invocation.getMethodName(), WEIGHT_KEY, DEFAULT_WEIGHT);
    
    // 如果设置了服务热身时间 且当前的服务上线时间还没到热身时间 会综合热身时间计算权重
	if (weight > 0) {
		long timestamp = invoker.getUrl().getParameter(REMOTE_TIMESTAMP_KEY, 0L);
		if (timestamp > 0L) {
			int uptime = (int) (System.currentTimeMillis() - timestamp);
			int warmup = invoker.getUrl().getParameter(WARMUP_KEY, DEFAULT_WARMUP);
			if (uptime > 0 && uptime < warmup) {
				weight = calculateWarmupWeight(uptime, warmup, weight);
			}
		}
	}
	return weight >= 0 ? weight : 0;
}

3.RandomLoadBalance

随机加权负载算法:假设我们有一组服务器 servers = [A, B, C],他们对应的权重为 weights = [5, 3, 2],权重总和为10。现在把这些权重值平铺在一维坐标值上,[0, 5) 区间属于服务器 A,[5, 8) 区间属于服务器 B,[8, 10) 区间属于服务器 C。接下来通过随机数生成器生成一个范围在 [0, 10) 之间的随机数,然后计算这个随机数会落到哪个区间上。比如数字3会落到服务器 A 对应的区间上,此时返回服务器 A 即可。

权重越大的机器,在坐标轴上对应的区间范围就越大,因此随机数生成器生成的数字就会有更大的概率落到此区间内。只要随机数生成器产生的随机数分布性很好,在经过多次选择后,每个服务器被选中的次数比例接近其权重比例。

protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
	
	int length = invokers.size();
	boolean sameWeight = true; // 是否权重相同
	int[] weights = new int[length]; // 权重数组 记录每个Invoker的权重
	
    // 拿到Invokers列表中第一个Invoker的权重
	int firstWeight = getWeight(invokers.get(0), invocation);
	weights[0] = firstWeight;
	
    // 统计所有Invoker的权重之和
	int totalWeight = firstWeight;
    
    // 遍历Invoker列表 将每个Invoker对应的权重保存进数组
    // 然后累加权重之和 判断每个Invoker权重是否相同
	for (int i = 1; i < length; i++) {
		int weight = getWeight(invokers.get(i), invocation);
		weights[i] = weight;
		totalWeight += weight;
		if (sameWeight && weight != firstWeight) {
			sameWeight = false;
		}
	}
    
    // 权重不相同的处理
    // 1.首先计算一个大于等于0、小于总权重的随机数,作为offset
    // 2.遍历权重数组,让每一个Invoker对应的权重去减offset,并更新offset值
    // 3.啥时候把这个offset减为小于等于0了,就说明当前权重对应的Invoker就是要选择的
	if (totalWeight > 0 && !sameWeight) {
		int offset 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值