在集群负载均衡时,Dubbo 提供了多种均衡策略,缺省为 random 随机调用。
以上是dubbo提供的四种负载均衡机制:
Random LoadBalance
随机,按权重设置随机概率。
在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。
比如:上图中userService有三台服务提供者,权重分别为100、200、50,按照基于权重的随机负载均衡机制,请求这三个服务的概率分别为2/7,4/7和1/7,我们可以测试下:
首先我们启动三个服务提供者UserService,端口分别为20880和20881、20882:
#dubbo协议使用的端口
dubbo.protocol.port=20880
#dubbo协议使用的端口
dubbo.protocol.port=20881
#dubbo协议使用的端口
dubbo.protocol.port=20882
并打印日志:
@Override
public List getALlUsers(){
logger.debug("getALlUsers in...1");
List users = userMapper.getAllUsers();
return users;
}
@Override
public List getALlUsers(){
logger.debug("getALlUsers in...2");
List users = userMapper.getAllUsers();
return users;
}
@Override
public List getALlUsers(){
logger.debug("getALlUsers in...3");
List users = userMapper.getAllUsers();
return users;
}
然后启动服务消费者,分别调用三次接口http://localhost:7777/getAllUsers:
第一次:
第二次:
第三次:
第四次:
通过观察控制台可以发现,这三个服务的权重都是100,是相等的,但是在随机策略下,以上的四次访问确实是没有规律的,其中第一个服务就被访问了2次,之后第三个服务才被访问到
RoundRobin LoadBalance
轮循,按公约后的权重设置轮循比率。
存在慢的提供者累积请求的问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。
测试:
我们将消费者引用的远程服务负载均衡策略改为轮询,此时我们仍然保证三个服务的权重相等。
@Reference(loadbalance="roundrobin")
private UserService userService;
然后重启消费者,分别调用四次接口:
第一次:
getALlUsers in...1
第二次:
getALlUsers in...2
第三次:
getALlUsers in...3
第四次:
getALlUsers in...1
getALlUsers in...1
可以看到在权重相等的情况下,使用轮询策略,消费者会依次访问三个服务。
然后我们将策略依然改成random:
@Reference(loadbalance="random")
private UserService userService;
然后我们可以在服务提供者的服务上添加权重的注解:
不过这样就写死了,我们平时最多的是动态的调整服务的权重,不采用图中配置,所以我们可以在控制台来动态配置:
最终调整的结果:
再次访问多次接口,我们可以发现随机策略下,权重大的会被访问到很多次,而权重小的则调用的少:
getALlUsers in...2
getALlUsers in...3
getALlUsers in...3
getALlUsers in...3
getALlUsers in...3
还有两种是:
LeastActive LoadBalance
最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。
使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。
ConsistentHash LoadBalance
一致性 Hash,相同参数的请求总是发到同一提供者。
当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。算法参见:http://en.wikipedia.org/wiki/Consistent_hashing
缺省只对第一个参数 Hash,如果要修改,请配置
缺省用 160 份虚拟节点,如果要修改,请配置
如有疑问,欢迎下方留言与我一起交流..