Dubbo-负载均衡原理解析

本文详细解析了Dubbo的负载均衡原理,包括轮询、加权轮询、一致性哈希和最小活跃数四种算法的实现和特点。通过代码示例展示了如何处理权重不相等的情况,以及如何在实践中应用这些算法以实现服务调用的均衡。
摘要由CSDN通过智能技术生成

for (int i = 0; i < weights.length; i++) {

Integer weight = (Integer) weights[i];

totalWeight += weight;

//判断权重是否都相等

if (sameWeight && i > 0 && !weight.equals(weights[i - 1])) {

sameWeight = false;

}

}

Random random = new Random();

int randomPos = random.nextInt(totalWeight);

//权重值不相等

if (!sameWeight) {

for (String ip : ServerIps.WEIGHT_LIST.keySet()) {

Integer value = ServerIps.WEIGHT_LIST.get(ip);

if (randomPos < value) {

return ip;

}

randomPos = randomPos - value;

}

}

return (String) ServerIps.WEIGHT_LIST.keySet().toArray()[new Random().nextInt(ServerIps.WEIGHT_LIST.size())];

}

public static void main(String[] args) {

//连续调用10次

for (int i = 0; i < 10; i++) {

System.out.println(getServer());

}

}

}

轮询算法-RoundRobinLoadBalance


特点

  • 加权轮询,按公约后的权重设置轮询比率,循环调用节点

  • 缺点:同样存在慢的提供者累积请求的问题。

代码实现(简单的轮询算法)

public class RoundRobin {

private static Integer pos = 0;

public static String getServer() {

String ip = “”;

//pos同步

synchronized (pos) {

if (pos >= ServerIps.LIST.size()) {

pos = 0;

}

ip = ServerIps.LIST.get(pos);

pos++;

}

return ip;

}

public static void main(String[] args) {

//连续调用10次

for (int i = 0; i < 11; i++) {

System.out.println(getServer());

}

}

}

执行结果如下:

192.168.0.1

192.168.0.2

192.168.0.3

192.168.0.4

192.168.0.5

192.168.0.6

192.168.0.7

192.168.0.8

192.168.0.9

192.168.0.10

192.168.0.1

这种算法很简单,也很公平,每台服务轮流来进行服务,但是有的机器性能好,所以能者多劳,和随机算法一样,加上权重维度以后,其中一种实现方法就是复制法,复制法的缺点是,比较消耗内存。

介绍另外一种算法:这种算法引入一个概念:调用编号,比如第1次调用为1,第2次调用为2,第100次调用为100,调用编号是递增的,所以我们可以根据这个调用编号推算出服务器。

假设我们有三台服务器servers = [A, B, C],对应的权重为 weights = [ 2, 5, 1], 总权重为8,我们可以理解为有8台“服务器”,这是8台“不具有并发功能”,其中有2台为A,5台为B,1台为C,一次调用过来的时候,需要按顺序访问,比如有10次调用,那么服务器调用顺序为AABBBBBCAA,调用编号会越来越大,而服务器是固定的,所以需要把调用编号“缩小”,这里对调用编号进行取余,除数为总权重和

比如:

  1. 1号调用,1%8=1;

  2. 2号调用,2%8=2;

  3. 3号调用,3%8=3;

  4. 8号调用,8%8=0;

  5. 9号调用,9%8=1;

  6. 100号调用,100%8=4;

我们发现调用编号可以被缩小为0-7之间的8个数字,问题是怎么根据这个8个数字找到对应的服务器呢?和我们随机算法类似,这里也可以把权重想象为一个坐标轴“0-----2-----7-----8”

  1. 1号调用,1%8=1,offset = 1, offset <= 2 is true,取A;

  2. 2号调用,2%8=2;offset = 2,offset <= 2 is true, 取A;

  3. 3号调用,3%8=3;offset = 3, offset <= 2 is false, offset = offset - 2, offset = 1, offset <= 5,取B

  4. 8号调用,8%8=0;offset = 0, 特殊情况,offset = 8,offset <= 2 is false, offset = offset - 2, offset = 6, offset <= 5 is false, offset = offset - 5, offset = 1, offset <= 1 is true, 取C;

  5. 9号调用,9%8=1;// …

  6. 100号调用,100%8=4; //…

模拟调用编号获取工具:

public class Sequence {

public static Integer num=0;

public static Integer getAndIncrement(){

return ++num;

}

}

public class WeightRoundRobin {

private static Integer pos = 0;

public static String getServer() {

int totalWeight = 0;

boolean sameWeight = true;

Object[] weights = ServerIps.WEIGHT_LIST.values().toArray();

for (int i = 0; i < weights.length; i++) {

Integer weight = (Integer) weights[i]

  • 27
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值