2万字长文带你细细盘点五种负载均衡策略( 四 )


看源码之前,我们的目标要十分明确,就是想要找到 Dubbo 最小活跃数算法的具体实现类以及实现类的具体逻辑是什么 。
根据我们的 provider.xml 里面的:

2万字长文带你细细盘点五种负载均衡策略

文章插图
 
很明显,我们知道 loadbalance 是关键字 。所以我们拿着 loadbalance 全局搜索,可以看到 Dubbo 包下面的 LoadBalance 。
2万字长文带你细细盘点五种负载均衡策略

文章插图
 
这是一个 SPI 接口 
com.alibaba.dubbo.rpc.cluster.LoadBalance:
2万字长文带你细细盘点五种负载均衡策略

文章插图
 
其实现类为:
com.alibaba.dubbo.rpc.cluster.loadbalance.AbstractLoadBalance
AbstractLoadBalance 是一个抽象类,该类里面有一个抽象方法doSelect 。这个抽象方法其中的一个实现类就是我们要分析的最少活跃次数负载均衡的源码 。
2万字长文带你细细盘点五种负载均衡策略

文章插图
 
同时,到这里我们知道了 LoadBalance 是一个 SPI 接口,说明我们可以扩展自己的负载均衡策略 。抽象方法 doSelect 有四个实现类 。这个四个实现类,就是 Dubbo 官方提供的负载均衡策略(截止 2.7.7 版本之前),他们分别是:
  1. ConsistentHashLoadBalance 一致性哈希算法
  2. LeastActiveLoadBalance 最小活跃数算法
  3. RandomLoadBalance 加权随机算法
  4. RoundRobinLoadBalance 加权轮询算法
我们已经找到了 LeastActiveLoadBalance 这个类了,那么我们的第二个断点打在哪里已经很明确了 。
2万字长文带你细细盘点五种负载均衡策略

文章插图
 
目前看来,两个断点就可以支撑我们的分析了 。
有的朋友可能想问,那我想知道 Dubbo 是怎么识别出我们想要的是最少活跃次数算法,而不是其他的算法呢?其他的算法是怎么实现的呢?从第一个断点到第二个断点直接有着怎样的调用链呢?
在没有彻底搞清楚最少活跃数算法之前,这些统统先记录在案但不予理睬 。一定要明确目标,带着一个问题进来,就先把带来的问题解决了 。之后再去解决在这个过程中碰到的其他问题 。在这样环环相扣解决问题的过程中,你就慢慢的把握了源码的精髓 。这是我个人的一点看源码的心得 。供诸君参考 。
模拟环境既然叫做最小活跃数策略 。那我们得让现有的三个消费者都有一些调用次数 。所以我们得改造一下服务提供者和消费者 。
服务提供者端的改造如下:
2万字长文带你细细盘点五种负载均衡策略

文章插图
 

2万字长文带你细细盘点五种负载均衡策略

文章插图
 
PS:这里以权重为 300 的服务端为例 。另外的两个服务端改造点相同 。
客户端的改造点如下:
2万字长文带你细细盘点五种负载均衡策略

文章插图
 
一共发送 21 个请求:其中前 20 个先发到服务端让其 hold 住(因为服务端有 sleep),最后一个请求就是我们需要 Debug 跟踪的请求 。
运行一下,让程序停在断点的地方,然后看看控制台的输出:
2万字长文带你细细盘点五种负载均衡策略

文章插图
 

2万字长文带你细细盘点五种负载均衡策略

文章插图
 

2万字长文带你细细盘点五种负载均衡策略

文章插图
 
权重为300的服务端共计收到9个请求
权重为200的服务端共计收到6个请求
默认权重的服务端共计收到5个请求
我们还有一个请求在 Debug 。直接进入到我们的第二个断点的位置,并 Debug 到下图所示的一行代码(可以点看查看大图):
2万字长文带你细细盘点五种负载均衡策略

文章插图
 
正如上面这图所说的:weight=100 回答了一个问题,active=0 提出的一个问题 。
weight=100 回答了什么问题呢?
默认权重是多少?是 100 。
我们服务端的活跃数分别应该是下面这样的
  • 权重为300的服务端,active=9
  • 权重为200的服务端,active=6
  • 默认权重(100)的服务端,active=5
但是这里为什么截图中的active会等于 0 呢?这是一个问题 。
继续往下 Debug 你会发现,每一个服务端的 active 都是 0 。所以相比之下没有一个 invoker 有最小 active。于是程序走到了根据权重选择 invoker 的逻辑中 。


推荐阅读