前言:
目前大家对“dubbo路由和负载均衡”大约比较注意,朋友们都需要知道一些“dubbo路由和负载均衡”的相关资讯。那么小编也在网摘上收集了一些有关“dubbo路由和负载均衡””的相关内容,希望兄弟们能喜欢,咱们快快来了解一下吧!Dubbo的五种负载均衡策略
2020 年 5 月 15 日,Dubbo 发布 2.7.7 release 版本。其中有这么一个 Features
新增一个负载均衡策略。
熟悉我的老读者肯定是知道的,Dubbo 的负载均衡我都写过专门的文章,对每个负载均衡算法进行了源码的解读,还分享了自己调试过程中的一些骚操作。
新的负载均衡出来了,那必须的得解读一波。
先看一下提交记录:
负载均衡是基于 SPI 实现的,我们看到对应的文件中多了一个名为 shortestresponse 的 key。
这个,就是新增的负载均衡策略了。看名字,你也知道了这个策略的名称就叫:最短响应。
所以截止 2.7.7 版本,官方提供了五种负载均衡算法了,他们分别是:
ConsistentHashLoadBalance 一致性哈希负载均衡LeastActiveLoadBalance 最小活跃数负载均衡RandomLoadBalance 加权随机负载均衡RoundRobinLoadBalance 加权轮询负载均衡ShortestResponseLoadBalance 最短响应时间负载均衡
前面四种我已经在之前的文章中进行了详细的分析。这次来分析分析最短响应时间负载均衡。
最短响应时间负载均衡
首先,我们看一下这个类上的注解,先有个整体的认知。
org.apache.dubbo.rpc.cluster.loadbalance.ShortestResponseLoadBalance
我来翻译一下是什么意思:
从多个服务提供者中选择出调用成功的且响应时间最短的服务提供者,由于满足这样条件的服务提供者有可能有多个。所以当选择出多个服务提供者后要根据他们的权重做分析。但是如果只选择出来了一个,直接用选出来这个。如果真的有多个,看它们的权重是否一样,如果不一样,则走加权随机算法的逻辑。如果它们的权重是一样的,则随机调用一个。
再配个图,就好理解了,可以先不管图片中的标号:
有了上面的整体概念的铺垫了,接下来分析源码的时候就简单了。
源码一共就 66 行,我把它分为 5 个片段去一一分析。
这里一到五的标号,对应上面流程图中的标号。我们一个个的说。
标号为①的部分
这一部分是定义并初始化一些参数,为接下来的代码服务的,翻译一下每个参数对应的注释:
length 参数:服务提供者的数量。
shortestResponse 参数:所有服务提供者的估计最短响应时间。(这个地方我觉得注释描述的不太准确,看后面的代码可以知道这只是一个零时变量,在循环中存储当前最短响应时间是多少。)
shortCount 参数:具有相同最短响应时间的服务提供者个数,初始化为 0。
shortestIndexes 参数:数组里面放的是具有相同最短响应时间的服务提供者的下标。
weights 参数:每一个服务提供者的权重。
totalWeight 参数:多个具有相同最短响应时间的服务提供者对应的预热(预热这个点还是挺重要的,在下面讲最小活跃数负载均衡的时候有详细说明)权重之和。
firstWeight 参数:第一个具有最短响应时间的服务提供者的权重。
sameWeight 参数:多个满足条件的提供者的权重是否一致。
标号为②的部分
这一部分代码的关键,就在上面框起来的部分。而框起来的部分,最关键的地方,就在于第一行。
获取调用成功的平均时间。
成功调用的平均时间怎么算的?
调用成功的请求数总数对应的总耗时 / 调用成功的请求数总数 = 成功调用的平均时间。
所以,在下面这个方法中,首先获取到了调用成功的请求数总数:
这个 succeeded 参数是怎么来的呢?
答案就是:总的请求数减去请求失败的数量,就是请求成功的总数!
那么为什么不能直接获取请求成功的总数呢?
别问,问就是没有这个选项啊。你看,在 RpcStatus 里面没有这个参数呀。
请求成功的总数我们有了,接下来成功总耗时怎么拿到的呢?
答案就是:总的请求时间减去请求失败的总时间,就是请求成功的总耗时!
那么为什么不能直接获取请求成功的总耗时呢?
别问,问就是......
我们看一下 RpcStatus 中的这几个参数是在哪里维护的:
org.apache.dubbo.rpc.RpcStatus#endCount(org.apache.dubbo.rpc.RpcStatus, long, boolean)
其中的第二个入参是本次请求调用时长,第三个入参是本次调用是否成功。
具体的方法不必细说了吧,已经显而易见了。
再回去看框起来的那三行代码:
第一行获取到了该服务提供者成功请求的平均耗时。第二行获取的是该服务提供者的活跃数,也就是堆积的请求数。第三行获取的就是如果当前这个请求发给这个服务提供者预计需要等待的时间。乘以 active 的原因是因为它需要排在堆积的请求的后面嘛。
这里,我们就获取到了如果选择当前循环中的服务提供者的预计等待时间是多长。
后面的代码怎么写?
当然是出来一个更短的就把这个踢出去呀,或者出来一个一样长时间的就记录一下,接着去 pk 权重了。
所以,接下来 shortestIndexes 参数和 weights 参数就排上用场了:
另外,多说一句的,它里面有这样的一行注释:
和 LeastActiveLoadBalance 负载均衡策略一致,我给你截图对比一下:
可以看到,确实是非常的相似,只是一个是判断谁的响应时间短,一个是判断谁的活跃数低。
标号为③的地方
标号为③的地方是这样的:
里面参数的含义我们都知道了,所以,标号为③的地方的含义就很好解释了:经过选择后只有一个服务提供者满足条件。所以,直接使用这个服务提供者。
标号为④的地方
这个地方我就不展开讲了(后面的加权随机负载均衡那一小节有详细说明),熟悉的朋友一眼就看出来这是加权随机负载均衡的写法了。
不信?我给你对比一下:
你看,是不是一模一样的。
标号为⑤的地方
一行代码,没啥说的。就是从多个满足条件的且权重一样的服务提供者中随机选择一个。
如果一定要多说一句的话,我截个图吧:
可以看到,这行代码在最短响应时间、加权随机、最小活跃数负载均衡策略中都出现了,且都在最后一行。
好了,到这里最短响应时间负载均衡策略就讲完了,你再回过头去看那张流程图,会发现其实流程非常的清晰,完全可以根据代码结构画出流程图。一个是说明这个算法是真的不复杂,另一个是说明好的代码会说话。
优雅
你知道 Dubbo 加入这个新的负载均衡算法提交了几个文件吗?
四个文件,其中还包含两个测试文件:
这里就是策略模式和 SPI 的好处。对原有的负载均衡策略没有任何侵略性。只需要按照规则扩展配置文件,实现对应接口即可。
这是什么?
这就是值得学习优雅!
总结
好了,到这里关于Dubbo的五种负载均衡策略就讲完了。简单总结一下:(加权随机算法在讲最小活跃数算法的时候提到过,因为原理十分简单,这里就不专门拿出章节来描述了。)
最短响应时间负载均衡:在所有服务提供者中选出平均响应时间最短的一个,如果能选出来,则使用选出来的一个。如果不能选出来多个,再根据权重选,如果权重也一样,则随机选择。
一致性哈希负载均衡:在一致性哈希算法中,不管是增加节点,还是宕机节点,受影响的区间仅仅是增加或者宕机服务器在哈希环空间中,逆时针方向遇到的第一台服务器之间的区间,其它区间不会受到影响。为了解决数据倾斜的问题,引入了虚拟节点的概念。一致性哈希算法是 Dubbo 中唯一一个与权重没有任何关系的负载均衡算法,可以保证相同参数的请求打到同一台机器上。
最小活跃数负载均衡:需要配合 activeFilter 使用,活跃数在方法调用前后进行维护,响应越快的服务器堆积的请求越少,对应的活跃数也少。Dubbo 在选择的时候遵循下面的规则,有最小活跃数用最小活跃数,没有最小活跃数根据权重选择,权重一样则随机返回的负载均衡算法。
加权随机算法:随机,顾名思义,就是从多个服务提供者中随机选择一个出来。加权,就是指需要按照权重设置随机概率。常见场景就是对于性能好的机器可以把对应的权重设置的大一点,而性能相对较差的,权重设置的小一点。哎,像极了这个社会上的某些现象,对外宣传是随机摇号,背后指不定有一群权重高的人呢。
加权轮询负载均衡:轮询就是雨露均沾的意思,所有的服务提供者都需要调用。而当轮询遇到加权则可以让请求(不论多少)严格按照我们的权重之比进行分配。比如有A、B、C三台服务器,权重之比为5:3:2,一共处理10个请求。那么采用负载均衡采用轮询加权算法时,A、B、C服务一定是分别承担5、3、2个请求。同时需要注意的是加权轮询算法的两次升级过程,以及最终的“平滑”的解决方案。
再说一件事
本文主要聊的是负载均衡嘛,让我想起了 2019 年阿里巴巴第五届中间件挑战赛的初赛赛题也是实现一个负载均衡策略。
具体的赛题可以看这里:
这种比赛还是很有意思的,你报名之后仅仅是读懂赛题,然后自己多想想怎么实现,哪怕是不提交代码,在比赛完成后看前几名的赛题分析,再去把他们的代码拉下来看看,你就会发现,其实最终的思路都大同小异,差别会体现在参数调优和代码优化程度上。
当然最大的差别还是会体现在语言的层面。如果不限制参数语言的话,Java 系的选手一定是被 C 系选手吊打的。
但是,被吊打不重要,重要的是真的能学到很多的东西,而这些东西,在绝大部分工作中是很难学到的。
最近,阿里巴巴第六届中间件挑战赛也开始了,可以看一下这个链接:
这次是分为三个赛道,选择性更多了。
作为这个比赛的长期关注者(持续关注三年了吧),这次作为一个自来水免费宣传一波。
朋友,我真心建议你去看一下,报个名,玩一玩,收获真的很大的。
当然,如果能在报名的时候邀请人那一栏填【why技术】,我真心感谢你。
最后说一句(求关注)
点个“赞”吧,周更很累的,不要白嫖我,需要一点正反馈。
才疏学浅,难免会有纰漏,如果你发现了错误的地方,还请你留言指出来,我对其加以修改。
感谢您的阅读,我坚持原创,十分欢迎并感谢您的关注。
我是 why,一个被代码耽误的文学创作者,不是大佬,但是喜欢分享,是一个又暖又有料的四川好男人。
标签: #dubbo路由和负载均衡