吐血输出:2万字长文带你细细盘点五种负载均衡策略。 (2)

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
网络型负载均衡 NLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
简介: 吐血输出:2万字长文带你细细盘点五种负载均衡策略。 (2)

断点打在哪?


相信很多朋友也很想看源码,但是不知道从何处下手。处于一种在源码里面"乱逛"的状态,一圈逛下来,收获并不大。


这一部分我想分享一下我是怎么去看源码。首先我会带着问题去源码里面寻找答案,即有针对性的看源码。


如果是这种框架类的,正如上面写的,我会先翻一翻官网(Dubbo 的官方文档其实写的挺好了),然后搭建一个简单的 Demo 项目,然后 Debug 跟进去看。Debug 的时候当然需要是设置断点的,那么这个断点如何设置呢?


第一个断点,当然毋庸置疑,是打在调用方法的地方,比如本文中,第一个断点是在这个地方:


接下里怎么办?


你当然可以从第一个断点处,一步一步的跟进去。但是在这个过程中,你发现了吗?大多数情况你都是被源码牵着鼻子走的。本来你就只带着一个问题去看源码的,有可能你Debug了十分钟,还没找到关键的代码。也有可能你Debug了十分钟,问题从一个变成了无数个


所以不要慌,我们点支烟,慢慢分析。


首先怎么避免被源码牵着四处乱逛呢?


我们得找到一个突破口,还记得我在《很开心,在使用mybatis的过程中我踩到一个坑》这篇文章中提到的逆向排查的方法吗?这次的文章,我再次展示一下该方法。


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


根据我们的 provider.xml 里面的:


很明显,我们知道 loadbalance 是关键字。所以我们拿着 loadbalance 全局搜索,可以看到 Dubbo 包下面的 LoadBalance。


这是一个 SPI 接口 com.alibaba.dubbo.rpc.cluster.LoadBalance:


其实现类为:


com.alibaba.dubbo.rpc.cluster.loadbalance.AbstractLoadBalance

AbstractLoadBalance 是一个抽象类,该类里面有一个抽象方法doSelect。这个抽象方法其中的一个实现类就是我们要分析的最少活跃次数负载均衡的源码。


同时,到这里我们知道了 LoadBalance 是一个 SPI 接口,说明我们可以扩展自己的负载均衡策略。抽象方法 doSelect 有四个实现类。这个四个实现类,就是 Dubbo 官方提供的负载均衡策略(截止 2.7.7 版本之前),他们分别是:


  1. ConsistentHashLoadBalance 一致性哈希算法
  2. LeastActiveLoadBalance 最小活跃数算法
  3. RandomLoadBalance 加权随机算法
  4. RoundRobinLoadBalance 加权轮询算法


我们已经找到了 LeastActiveLoadBalance 这个类了,那么我们的第二个断点打在哪里已经很明确了。


目前看来,两个断点就可以支撑我们的分析了。


有的朋友可能想问,那我想知道 Dubbo 是怎么识别出我们想要的是最少活跃次数算法,而不是其他的算法呢?其他的算法是怎么实现的呢?从第一个断点到第二个断点直接有着怎样的调用链呢?


在没有彻底搞清楚最少活跃数算法之前,这些统统先记录在案但不予理睬。一定要明确目标,带着一个问题进来,就先把带来的问题解决了。之后再去解决在这个过程中碰到的其他问题。在这样环环相扣解决问题的过程中,你就慢慢的把握了源码的精髓。这是我个人的一点看源码的心得。供诸君参考。


模拟环境


既然叫做最小活跃数策略。那我们得让现有的三个消费者都有一些调用次数。所以我们得改造一下服务提供者和消费者。


服务提供者端的改造如下:


PS:这里以权重为 300 的服务端为例。另外的两个服务端改造点相同。


客户端的改造点如下:


一共发送 21 个请求:其中前 20 个先发到服务端让其 hold 住(因为服务端有 sleep),最后一个请求就是我们需要 Debug 跟踪的请求。

运行一下,让程序停在断点的地方,然后看看控制台的输出:


权重为300的服务端共计收到9个请求


权重为200的服务端共计收到6个请求


默认权重的服务端共计收到5个请求


我们还有一个请求在 Debug。直接进入到我们的第二个断点的位置,并 Debug 到下图所示的一行代码(可以点看查看大图):


正如上面这图所说的:weight=100 回答了一个问题,active=0 提出的一个问题。

weight=100 回答了什么问题呢?


默认权重是多少?是 100。


我们服务端的活跃数分别应该是下面这样的


  • 权重为300的服务端,active=9
  • 权重为200的服务端,active=6
  • 默认权重(100)的服务端,active=5


但是这里为什么截图中的active会等于 0 呢?这是一个问题。


继续往下 Debug 你会发现,每一个服务端的 active 都是 0。所以相比之下没有一个 invoker 有最小 active 。于是程序走到了根据权重选择 invoker 的逻辑中。


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
相关实践学习
部署高可用架构
本场景主要介绍如何使用云服务器ECS、负载均衡SLB、云数据库RDS和数据传输服务产品来部署多可用区高可用架构。
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
目录
相关文章
|
2月前
|
负载均衡 监控 算法
实现负载均衡策略:优化系统性能与可用性
实现负载均衡策略:优化系统性能与可用性
|
2月前
|
负载均衡 Dubbo 应用服务中间件
【Dubbo 解析】Dubbo支持几种负载均衡策略?
【1月更文挑战第11天】【Dubbo 解析】Dubbo支持几种负载均衡策略?
|
2月前
|
域名解析 缓存 运维
【域名解析DNS专栏】DNS解析策略:如何实现负载均衡与故障转移
【5月更文挑战第23天】DNS在互联网中扮演关键角色,将域名转换为IP地址。本文探讨DNS的负载均衡和故障转移技术,以增强服务可用性和性能。负载均衡包括轮询(简单分配流量)和加权轮询(按服务器处理能力分配)。故障转移通过主备策略和TTL值实现快速切换,确保服务连续性。实践案例展示了在电商网站如何应用这些策略。DNS策略优化可提升网站速度和稳定性,借助云服务和智能工具,DNS管理更加高效。
【域名解析DNS专栏】DNS解析策略:如何实现负载均衡与故障转移
|
2月前
|
负载均衡
【SpringCloud】Ribbon负载均衡原理、负载均衡策略、饥饿加载
【SpringCloud】Ribbon负载均衡原理、负载均衡策略、饥饿加载
27 0
|
2月前
|
负载均衡 关系型数据库 分布式数据库
【PolarDB开源】PolarDB读写分离实践:优化读取性能与负载均衡策略
【5月更文挑战第26天】PolarDB是云原生关系型数据库,通过读写分离优化性能和扩展性。它设置主节点处理写操作,从节点处理读操作,异步复制保证数据一致性。优化读取性能的策略包括增加从节点数量、使用只读实例和智能分配读请求。负载均衡策略涉及基于权重、连接数和地理位置的分配。实践示例中,电商网站通过主从架构、只读实例和负载均衡策略提升商品查询效率。PolarDB的读写分离与负载均衡为企业应对大数据和高并发提供了有效解决方案。
142 0
|
2月前
|
负载均衡
Ribbon负载均衡策略
Ribbon负载均衡策略
|
2月前
|
负载均衡 算法 Java
Ribbon的负载均衡策略
Ribbon的负载均衡策略
45 2
|
2月前
|
负载均衡 关系型数据库 MySQL
MySQL Router读写节点支持负载均衡策略
`routing_strategy`是MySQL Router配置选项,用于设定数据路由策略。可选值包括:`first-available`, `next-available`, `round-robin`和`round-robin-with-fallback`,分别对应不同的负载均衡和故障转移策略。更多详情参考:<https://dev.mysql.com/doc/mysql-router/8.0/en/mysql-router-conf-options.html#option_mysqlrouter_routing_strategy>。
44 1
|
2月前
|
缓存 负载均衡 应用服务中间件
nginx的各种负载均衡策略与各种负载均衡策略如何配置
Nginx支持多种负载均衡策略,如轮询、加权轮询、IP哈希、最少连接、URL哈希和fair策略。轮询是默认策略,每个请求按顺序分发;加权轮询根据权重分配请求;IP哈希确保相同IP的请求始终发送到同一服务器;最少连接将请求发送给连接数最少的服务器;URL哈希(需额外工具或模块)和fair策略则依据URL和响应时间分配请求。配置变更需更新nginx.conf并重新加载或重启服务,具体配置应参照官方文档。
81 0
|
2月前
|
负载均衡 算法 Serverless
负载均衡策略
负载均衡策略
54 0