开发者学堂课程【阿里巴巴分布式服务框架 Dubbo 快速入门:负载均衡机制】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/624/detail/9473
负载均衡机制
内容介绍:
一、dubbo 默认支持多种负载均衡策略
二、测试负载均衡策略
三、如何改变 dubbo 负载均衡机制
一、dubbo 默认支持多种负载均衡策略
1、Random:基于权重的随机负载均衡机制
据上图,比如 orderService 想要调用 userService,userService 分别在1、2、3三台机器,可以为每一台机器服务设置权重,第一台权重为100;第二台权重为200;第三台权重为50,合起来三台权重为350,对于一号机器来说,它的概率为100/350,即2/7;在负载均衡的情况下,大量请求过来,大约有2/7的请求来到第一台机器,4/7的请求来到第二台机器,有1/7的请求来到第三台机器,权重相当于一个概率分布。
如果第一次调用第一台机器,那么第二次不一定调用第二台机器还是第三台机器,有可能还落在第一台机器,但总体上按照大量请求概率分布来看,1号机器会占2/7的概率,这是随机方式的负载权衡,下一次调用也不知道在哪,但总概率大约是这么多。
2、RoundRobin:基于权重轮循负载均衡机制。
据上图,第二点基于权重的轮询负载均衡机制,如果没有权重的方式,也有一个轮询,即我们忽略掉权重,只看轮询,那么 orderService 调 userService,轮询情况下是一一访问,比如第一个请求过来先用1号机器的 userService 服务,第二次又发一个请求过来,按照轮询机制轮到2号机器,2号机器处理完毕,如果还有 userService 请求过来,轮到3号机器,再下一次又轮到第1号、第2号、第3号。
以上是按照轮询的方式,每一个机器都轮到一次,但可以加上权重的轮询,依旧按照以前方式设置权重,相当于2/7的概率到1号机器,4/7的概率到2号机器,1/7的概率到3号机器。
如果是第一个服务器调完,第二个服务器不知道在哪,但在轮询的情况下,第一个调完必须来到第二个。假如有七次请求,第一次请求过来调1号机器,第二次请求按轮询调2号机器,第三次请求按轮询调3号机器,第四次请求还是到1号机器,第五次请求到2号机器,但第六次请求本应该到3号机器,在七次请求中,1号机器占两次,二号占4次,3号机器只能占1次,在第一次轮询时,3号已经用过了,那么第六次请求来到1号机器发现2次已经用过了,所以第六次请求来到2号机器。
接下来第七次请求,本该是第二轮来到1号机器,但1号机器已经用过了,也就来到2号机器。因此,访问是有顺序的,并且顺序要考虑权重值的,这是按照轮询的负载。
3、LeastActive:最少活跃数-负载均衡机制
orderService 调 userService,可能会来到任意一个服务器,这种情况下,要来到哪里,总会找到哪一个服务器会统计上一次的调用时间,比如第一个服务器,上次请求用了100ms,第二个服务器请求用了1000ms,第三个服务器请求用了300ms,说明第一个服务器快,orderService 会来到第一个服务器,下一次会在调哪个服务器之前问一下服务器上一次处理请求花了多长时间,总是挑一个响应速度最快的服务器,这叫最小活跃数。
4、ConsistentHash:一致性 hash-负载均衡体制
当 ordService 想要调用 userService 服务时,都调的是同一个方法,比如 getUser?id=1,按照 hash 分布,会来到1号机器,如果是 getUser?id=2,会来到2号机器,getUser?id=3,会来到三号机器,若一直发 getUser?id=1,也只会来到1号机器;只要方法名、参数名都一样,都落在同一台机器。
以上四种负载均衡算法的解释。
二、测试负载均衡策略
1、打开注册中心 zookeeper,注册多个服务
把 userServiceProvider 注册上多个,进行调用打印
第一个代码为@Override
public List<UserAddress>getUserAddressList(String userId) {
//TODO Auto-generated method stub
System.out.println(“UserServiceImpl…1……”);
user Service 先从20880端口暴露,代码为protocol Config.setPort(20880);
启动服务
第二个代码为@Override
public List<UserAddress>getUserAddressList(String userId) {
//TODO Auto-generated method stub
System.out.println(“UserServiceImpl…2……”);
user Service 从20881端口暴露,
代码为protocol Config.setPort(20881);
启动服务
第三个代码为@Override
public List<UserAddress>getUserAddressList(String userId) {
//TODO Auto-generated method stub
System.out.println(“UserServiceImpl…3……”);
user Service 从20881端口暴露,
代码为 protocol Config.setPort(20882);启动服务
相当于有三个服务提供者,刷新控制台,监控台显示提供者数3,应用数1(均为 user service provider)。
2、启动消费者 OrderService
启动前,把上节课配置的 dubbo 直连去掉,否则消费者会绕过注册中心。
启动起来后,注册中心首页已显示消费者数1,接下来看调用哪台机器,把控制台清空掉,第一次调用,进行刷新,二号控制台已打印;再进行刷新,一号控制台已打印;再刷新,一号控制台又打印;再进行刷新,1号控制台又打印;会发现这是一个随机按照权重的分配,也就是说并没有在轮询;得出的结论是 dubbo 中默认用的是随机负载均衡机制。
三、如何改变 dubbo 负载均衡机制
参照官方文档
服务端服务级别
<dubbo:service interface=”…”loadbalance=”roundrobin”/>
客户端服务级别
<dubbo:reference interface=”…”loadbalance=”roundrobin”/>
服务端服务级别
<dubbo:service interface=”…”>
<dubbo:method name=”…” loadbalance=”roundrobin”/>
<dubbo:service>
客户端方法级别
<dubbo:service interface=”…”>
<dubbo:method name=”…” loadbalance=”roundrobin”/>
<dubbo:reference>
负载均衡取值种数:
在消费者里,把负载均衡配置改为 @Reference (loadbalance=“roundbin”),关闭 order service 进行重新测试,启动起来,现在相当于用轮询的方式,一个访问接着下一个访问,清空其他控制台,重新刷新控制台,只有一个消费者,第一次进行调用时1号控制台,如果改成轮询,第二次进行调用是2号控制台,第三次刷新进行调用是3号调用台,再刷新一次进行调用落在1号控制台。
如果将负载均衡配置改为@Reference (loadbalance=“random”)//权重,调节权重有两种方案,
第一种再 userservice 中,可在暴露服务中说当前机器权重是多少,如@service(weight),
一般需要动态调整,dubbo 可在控制台找到所有服务提供者,有快速的倍权和半权,倍权是提升一倍的权重,半权是降一半的权重。返回控制台,把以前没调的 orderservice 停掉,重新启动 orderservice,用 random 机制,即@Reference (loadbalance=“random”),
启动后快速将提供者中第一个降为半权,权重从100变为50;将第二个倍权两次,权重从100变为400,第三个权重不变100;接下里进行调用测试,多次请求都在哪个服务器上,多次进行刷新,控制台显示 User ServiceImpl…1…打印2次, UserServiceImpl…2…打印了很多次, UserServiceImpl…3…打印了2次,可以看到400权重的会被多次调用,其他权重的少概率调用,在大量请求过来之后,会发现第一个概率为50/550,第三个概率为100/500,会遵循概率分布,以后课通过控制台对于某些性能不佳的服务器,通过快速调节权重的方式让其提供少量服务,也可在权重调节处,精确的指定某一个的权重。