
文章插图
active为什么是0?active 为 0 说明在 Dubbo 调用的过程中 active 并没有发生变化 。那 active 为什么是 0,其实就是在问 active 什么时候发生变化?
要回答这个问题我们得知道 active 是在哪里定义的,因为在其定义的地方,必有其修改的方法 。
下面这图说明了active是定义在RpcStatus类里面的一个类型为AtomicInteger 的成员变量 。

文章插图
在 RpcStatus 类中,有三处()调用 active 值的方法,一个增加、一个减少、一个获取:

文章插图
很明显,我们需要看的是第一个,在哪里增加 。
所以我们找到了 beginCount(URL,String) 方法,该方法只有两个 Filter 调用 。ActiveLimitFilter,见名知意,这就是我们要找的东西 。

文章插图
com.alibaba.dubbo.rpc.filter.ActiveLimitFilter具体如下:

文章插图
看到这里,我们就知道怎么去回答这个问题了:为什么active是0呢?因为在客户端没有配置ActiveLimitFilter 。所以,ActiveLimitFilter没有生效,导致active没有发生变化 。
怎么让其生效呢?已经呼之欲出了 。

文章插图
好了,再来试验一次:

文章插图

文章插图

文章插图
加上Filter之后,我们通过Debug可以看到,对应权重的活跃数就和我们预期的是一致的了 。
1.权重为300的活跃数为6
2.权重为200的活跃数为11
3.默认权重(100)的活跃数为3

文章插图
根据活跃数我们可以分析出来,最后我们Debug住的这个请求,一定会选择默认权重的invoker去执行,因为他是当前活跃数最小的invoker 。如下所示:

文章插图
虽然到这里我们还没开始进行源码的分析,只是把流程梳理清楚了 。但是把Demo完整的搭建了起来,而且知道了最少活跃数负载均衡算法必须配合ActiveLimitFilter使用,位于RpcStatus类的active字段才会起作用,否则,它就是一个基于权重的算法 。
比起其他地方直接告诉你,要配置ActiveLimitFilter才行哦,我们自己实验得出的结论,能让我们的印象更加深刻 。
我们再仔细看一下加上ActiveLimitFilter之后的各个服务的活跃数情况:
- 权重为300的活跃数为6
- 权重为200的活跃数为11
- 默认权重(100)的活跃数为3
其在业务上的含义是:我们有三台性能各异的服务器,A服务器性能最好,所以权重为300,B服务器性能中等,所以权重为200,C服务器性能最差,所以权重为100 。
当我们选择最小活跃次数的负载均衡算法时,我们期望的是性能最好的A服务器承担更多的请求,而真实的情况是性能中等的B服务器承担的请求更多 。这与我们的设定相悖 。
如果你说20个请求数据量太少,可能是巧合,不足以说明问题 。说明你还没被我带偏,我们不能基于巧合编程 。
所以为了验证这个地方确实有问题,我把请求扩大到一万个 。

文章插图
同时,记得扩大 provider 端的 Dubbo 线程池:

文章插图
由于每个服务端运行的代码都是一样的,所以我们期望的结果应该是权重最高的承担更多的请求 。但是最终的结果如图所示:

文章插图
各个服务器均摊了请求 。这就是我文章最开始的时候说的Dubbo 2.6.0 版本中最小活跃数负载均衡算法的Bug之一 。
接下来,我们带着这个问题,去分析源码 。
推荐阅读
- 带你走进潮汕工夫茶,工夫茶点心
- 带你了解安徽四大名茶,安徽茶打四大品牌
- 带你去看美团架构
- 万字长文讲解编码知识,看这文就够了!| 原力计划
- 一文带你彻底理解Linux的各种终端类型及概念
- 一篇长文学懂入门推荐算法库:surprise
- 电力负荷怎么计算?几分钟带你了解清楚,好东西,赶紧收藏
- 最新百度信息流产品手册,带你全面了解百度产品
- 三分钟带你了解香槟产区另一面,谈香槟,你也是行家
- 没有人比我更懂电流,今天带你重新认识电流
