Dubbo 的负载均衡策略:随机策略

本文介绍 Dubbo 的负载均衡策略中的随机策略。

1

什么是负载均衡策略

应用服务化之后,每一个应用都是多个服务组合成的,每个服务有多个实例,比如一个登录操作,需要调用登录接口 API,登录接口 API 不止一个,这时,调用哪个登录接口 API 就需要进行选择,这个选择过程就叫做负载均衡,会使用不同的算法来实现负载均衡策略。

Dubbo 提供了如下 4 个负载均衡策略。

2

随机负载均衡策略

Dubbo 中的随机负载均衡策略的实现类是: RandomLoadBalance ,它分为 2 种情况。

被调用服务的所有实例都是同等权重的,则随机生成一个从 0 到 实例数量 - 1 的数,并返回对应的实例。

比如:总共有 3 个实例 invokers,3 个实例的权重都为 100,随机生成一个从 0 到 2 的数,假设生成 2,则返回 invokers[2],也就是返回了第 3 个实例。

被调用服务的所有实例的权重不一,则累计所有权重 totalWeight,随机生成一个从 0 到 totalWeight - 1 的数 offset,定位 offset 所在的位置,并返回对应位置的实例。

比如:下图有 5 个实例,每个实例的权重不一样,分别如表格所示,要选择实例的时候,随机生成一个从 0 到 649 的数,假设生成 251,则落在 250 - 349 的范围内,也就是选中 C 实例。

这 2 种情况有什么不同呢?

第一种情况就是纯随机的策略;第二种情况则在随机的基础上,加上了权重因素,权重越大,被选择的可能性就越大。

3

随机策略的优缺点

优点:实现简单,水平扩展方便

缺点:当机器有异常的时候,不能根据机器的异常情况分配。

4

RandomLoadBalance 源码

public classRandomLoadBalanceextendsAbstractLoadBalance {

public static finalStringNAME="random";

private finalRandomrandom=newRandom();

@Override

protected InvokerdoSelect(List> invokers,URL url,Invocation invocation) {

// 待选择的被调用服务的实例数量

intlength = invokers.size();// Number of invokers

// 统计总权重

inttotalWeight =;// The sum of weights

// 标识:每个被调用服务的实例的权重是否相同

booleansameWeight =true;// Every invoker has the same weight?

// 遍历每个被调用服务,获取每个被调用服务的权重,统计所有权重之和,并判断每个调用服务的权重是否相同

for(inti =;i

intweight = getWeight(invokers.get(i),invocation);

totalWeight += weight;// Sum

if(sameWeight && i >

&& weight != getWeight(invokers.get(i -1),invocation)) {

// 有不相同的权重,则标识 sameWeight 为 false

sameWeight =false;

}

}

// 总权重大于 0 且 被调用服务权重有不相同的,则随机产生一个 0 到 totalWeight-1 的数,定位到该数是在哪个被调用方的范围内

if(totalWeight >&& !sameWeight) {

// If (not every invoker has the same weight & at least one invoker's weight>0), select randomly based on totalWeight.

intoffset =random.nextInt(totalWeight);

// Return a invoker based on the random value.

for(inti =;i

offset -= getWeight(invokers.get(i),invocation);

if(offset

returninvokers.get(i);

}

}

}

// 所有的被调用服务的权重相同,则随机产生一个 0 到 length-1 的数,返回对应的被调用服务

// If all invokers have the same weight value or totalWeight=0, return evenly.

returninvokers.get(random.nextInt(length));

}

}

做个有梦想的程序猿

  • 发表于:
  • 原文链接:https://kuaibao.qq.com/s/20180810G0URLL00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券