dubbo负载均衡
dubbo
一.同一个dubbo生产者服务怎么分布在不同服务器,且能进行负载均衡?
只要两个服务的id,接口,实现类一致(且dubbo:application名称一致,表示同一应用),注册到同一zookeeper。
Dubbo 定义了集群接口 Cluster 以及 Cluster Invoker。集群 Cluster 用途是将多个服务提供者合并为一个 Cluster Invoker,并将这个 Invoker 暴露给服务消费者。这样一来,服务消费者只需通过这个 Invoker 进行远程调用即可。
此时,消费者调用接口时,是一个可简单类比为 List。有多个Invoker,那么选择哪个invoker就成了一个问题。(负载均衡)
二.负载均衡(LoadBalance )
所有负载均衡算法继承AbstractLoadBalance。
执行过程:
1.执行select():首先会检测 invokers 集合的合法性,然后再检测 invokers 集合元素数量。如果只包含一个 Invoker,直接返回该 Inovker 即可。如果包含多个 Invoker,此时需要通过负载均衡算法doSelect()选择一个 Invoker。
2.执行doSelect():抽象方法,根据实现类的不同,实现不同方式负载均衡。
3.执行getWeight():每个抽象方法都需要获得权重(公共逻辑)。权重初始状态并非完全是配置的那样,还根据服务运行时间有关。
服务预热是一个优化手段,与此类似的还有 JVM 预热。主要目的是让服务启动后“低功率”运行一段时间,使其效率慢慢提升至最佳状态。
1.RandomLoadBalance加权随机
顾名思义,就是分配权值,随机将请求落在相应的权值区间。将Invoker按顺序排列。
int ran=Random.nextInt(allInvokeWeight);//取随机数,在权值范围
for (int i=0;i<Invoker.length;ii++{
ran-=Invoker.get(i).getWeight;
if (ran < 0){
return Invoker.get(i)//命中该区域
}
}
2.LeastActiveLoadBalance最小活跃数负载均衡
为什么是最小活跃数?每个请求服务时,活跃数就会+1,而处理完一个请求就会-1。所以最小活跃数的机器可以认为是处理能力很强,或者比较空闲的机器。但是此算法也还是跟权值有关,是基于加权最小活跃数算法实现的。算法过程:
- 遍历 invokers 列表,寻找活跃数最小的 Invoker
- 如果有多个 Invoker 具有相同的最小活跃数,此时记录下这些 Invoker 在 invokers 集合中的下标,并累加它们的权重,比较它们的权重值是否相等
- 如果只有一个 Invoker 具有最小的活跃数,此时直接返回该 Invoker 即可
- 如果有多个 Invoker 具有最小活跃数,且它们的权重不相等,此时处理方式和 RandomLoadBalance 一致
- 如果有多个 Invoker 具有最小活跃数,但它们的权重相等,此时随机返回一个即可
(简单来说找活跃最小的,活跃一致且权重不一致按随机权重,活跃一致权重一致则随机一个)
3.ConsistentHashLoadBalance一致性 hash 算法

每个Invoke生成(根据ip或者其他信息)一个hash值,落在一个环形区域。每个消费者请求也会生成一个hash值,对于每个请求hash都会被大于他们的invoke的hash值命中。如果当前节点挂了,则在下一次查询或写入缓存时,为缓存项查找另一个大于其 hash 值的缓存节点即可。这样就可以完成负载分配了,但是还有一个问题,均衡?这样生成的invoke的hash值,并不能控制谁的区域大,谁的区域小。出现数据倾斜。
这里相同颜色的节点均属于同一个服务提供者,比如 Invoker1-1,Invoker1-2,……, Invoker1-160。这样做的目的是通过引入虚拟节点,让 Invoker 在圆环上分散开来,避免数据倾斜问题。(相当于通过增加多个虚拟节点,来控制命中范围)

4.RoundRobinLoadBalance加权轮询负载均衡
比如服务器 A、B、C 权重比为 5:2:1。那么在8次请求中,服务器 A 将收到其中的5次请求,服务器 B 会收到其中的2次请求,服务器 C 则收到其中的1次请求。(和随机不一样,这里就相当于明确了每个机器的命中,按顺序进行)
三.网络协议
长连接:避免频繁创建线程进行连接。
| 协议名称 | 实现描述 | 连接 | 使用场景 |
|---|---|---|---|
| dubbo | 传输:mina、netty、grizzy 序列化:dubbo、hessian2、java、json | dubbo缺省采用单一长连接和NIO异步通讯 | 1.适合于小数据量大并发的服务调用 2.消费者 比提供者多 3.不适合传送大数据量的服务,比如文件、传视频 |
| rmi | 传输:java rmi 序列化:java 标准序列化 | 连接个数:多连接 连接方式:短连接 传输协议:TCP/IP 传输方式:BIO | 1.常规RPC调用 2.与原RMI客户端互操作 3.可传文件 4.不支持防火墙穿透 |
| hessian | 传输:Serverlet容器 序列化:hessian二进制序列化 | 连接个数:多连接 连接方式:短连接 传输协议:HTTP 传输方式:同步传输 | 1.提供者比消费者多 2.可传文件 3.跨语言传输 |
| http | 传输:servlet容器 序列化:表单序列化 | 连接个数:多连接 连接方式:短连接 传输协议:HTTP 传输方式:同步传输 | 1.提供者多余消费者 2.数据包混合 |
| webservice | 传输:HTTP 序列化:SOAP文件序列化 | 连接个数:多连接 连接方式:短连接 传输协议:HTTP 传输方式:同步传输 | 1.系统集成 2.跨语言调用 |
| thrift | 与thrift RPC实现集成,并在基础上修改了报文头 | 长连接、NIO异步传输 |
一直有个疑问?啥叫序列化?
序列化是指,将对象进行某种格式(二进制,json等)序列化,在网络上进行传输,然后进行反序列化成对象。
实现了Serizalible接口,并不能序列化,仅仅只是标记了你可以序列化。真正的序列化还是需要自己实现,如java序列化:
通过ObjectOutputStream,ObjectInputStream,进行java类的序列化。
所以dubbo支持的序列化,就是在传输的时候,使用配置好的序列化协议,例如hessian2。
三. Dubbo SPI 示例(增强javaSPI)
Dubbo 并未使用 Java SPI,而是重新实现了一套功能更强的 SPI 机制。Dubbo SPI 的相关逻辑被封装在了 ExtensionLoader 类中,通过 ExtensionLoader,我们可以加载指定的实现类。Dubbo SPI 所需的配置文件需放置在 META-INF/dubbo 路径下,配置内容如下。
optimusPrime = org.apache.spi.OptimusPrime
bumblebee = org.apache.spi.Bumblebee
与 Java SPI 实现类配置不同,Dubbo SPI 是通过键值对的方式进行配置,这样我们可以按需加载指定的实现类。另外,在测试 Dubbo SPI 时,需要在 Robot 接口上标注 @SPI 注解。下面来演示 Dubbo SPI 的用法:
public class DubboSPITest {
@Test
public void sayHello() throws Exception {
ExtensionLoader<Robot> extensionLoader =
ExtensionLoader.getExtensionLoader(Robot.class);
Robot optimusPrime = extensionLoader.getExtension("optimusPrime");//可以获得明确的实现类
optimusPrime.sayHello();
Robot bumblebee = extensionLoader.getExtension("bumblebee");
bumblebee.sayHello();
}
}
(虽然dubbo分为十层架构,但是他的内核所有层次都是基于SPI,每层的接口都含有@SPI)
dubbo负载均衡的更多相关文章
- Dubbo负载均衡与集群容错机制
1 Dubbo简介 Dubbo是一款高性能.轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现. 作为一个轻量级RPC框架,D ...
- dubbo负载均衡策略和集群容错策略都有哪些
dubbo负载均衡策略 random loadbalance 默认情况下,dubbo是random load balance随机调用实现负载均衡,可以对provider不同实例设置不同的权重,会按照权 ...
- dubbo负载均衡策略和集群容错策略
dubbo负载均衡策略 random loadbalance 默认情况下,dubbo是random load balance随机调用实现负载均衡,可以对provider不同实例设置不同的权重,会按照权 ...
- 一文讲透Dubbo负载均衡之最小活跃数算法
本文是对于Dubbo负载均衡策略之一的最小活跃数算法的详细分析.文中所示源码,没有特别标注的地方均为2.6.0版本. 为什么没有用截止目前的最新的版本号2.7.4.1呢?因为2.6.0这个版本里面有两 ...
- 3.dubbo 负载均衡策略和集群容错策略都有哪些?动态代理策略呢?
作者:中华石杉 面试题 dubbo 负载均衡策略和集群容错策略都有哪些?动态代理策略呢? 面试官心理分析 继续深问吧,这些都是用 dubbo 必须知道的一些东西,你得知道基本原理,知道序列化是什么协议 ...
- 分布式的几件小事(四)dubbo负载均衡策略和集群容错策略
1.dubbo负载均衡策略 ①random loadbalance 策略 默认情况下,dubbo是random loadbalance 随机调用实现负载均衡,可以对provider不同实例设置不同的权 ...
- Dubbo入门到精通学习笔记(十一):Dubbo服务启动依赖检查、Dubbo负载均衡策略、Dubbo线程模型(结合Linux线程数限制配置的实战分享)
文章目录 Dubbo服务启动依赖检查 Dubbo负载均衡策略 Dubbo线程模型(结合Linux线程数限制配置的实战分享) 实战经验分享( ** 属用性能调优**): Dubbo服务启动依赖检查 Du ...
- 面试系列24 dubbo负载均衡策略和集群容错策略
(1)dubbo负载均衡策略 1)random loadbalance 默认情况下,dubbo是random load balance随机调用实现负载均衡,可以对provider不同实例设置不同的权重 ...
- 面试系列16 dubbo负载均衡策略和集群容错策略都有哪些?动态代理策略呢
(1)dubbo负载均衡策略 1)random loadbalance 默认情况下,dubbo是random load balance随机调用实现负载均衡,可以对provider不同实例设置不同的权重 ...
- Dubbo 负载均衡的实现
前言 负载均衡是指在集群中,将多个数据请求分散在不同单元上进行执行,主要为了提高系统容错能力和加强系统对数据的处理能力. 在 Dubbo 中,一次服务的调用就是对所有实体域 Invoker 的一次筛选 ...
随机推荐
- python - 基础局部变量和全局变量
python中全局变量和局部变量的最大区别在于局部变量只能通过函数去访问,而全局变量可以直接访问 首先我们来看下什么是全局变量和局部变量 全局变量:在函数之外定义的变量,所有函数内可以调用这个全局变量 ...
- apache+djnago+websocket 部署配置
部署Apache服务器 1.apache服务的安装这里不做赘述,因为网上一大堆. 链接:https://blog.csdn.net/qq_24394093/article/details/905501 ...
- 用C++基础语句写一个五子棋游戏
(这是一个颜色会变化的呦) #include <iostream> using namespace std; int b[][]; int n; int m; void qipan() { ...
- Linux C++实现一服务器与多客户端之间的通信
通过网络查找资料得到的都是一些零碎不成体系的知识点,无法融会贯通.而且需要筛选有用的信息,这需要花费大量的时间.所以把写代码过程中用到的相关知识的博客链接附在用到的位置,方便回顾. 1.程序流程 服务 ...
- JavaScript设计模式之命令模式【命令解耦】
在讲解命令模式之前我们先来了解一个生活中的命令模式场景: 场景1: 医院看病抓药: 当你因为肾虚到医院看医生,医生一番操作之后得出结论:要吃个疗程[夏桑菊].[小柴胡](药名纯属虚构,真的肾虚就找医生 ...
- k8s 辨析 port、NodePort、targetPort、containerPort 区别
刚接触 k8s 涉及到端口到内容较多,容易混淆,这里整理如下: 目录 nodePort port targetPort containerPort 参考文章 nodePort nodePort 提供了 ...
- 第5篇 Scrum冲刺博客
1.站立式会议 1.1 会议图片 1.2 项目进展 成员 昨日任务 今日计划完成任务 陈忠明 歌曲信息的上传/下载包 歌曲批量下载压缩包 吴茂平 完善评论系统 新消息提醒功能设计 黄海钊 修改代码规范 ...
- Spring Boot入门系列(十九)整合mybatis,使用注解实现动态Sql、参数传递等常用操作!
前面介绍了Spring Boot 整合mybatis 使用注解的方式实现数据库操作,介绍了如何自动生成注解版的mapper 和pojo类. 接下来介绍使用mybatis 常用注解以及如何传参数等数据库 ...
- RedHat 6.8 离线安装Docker (rpm包安装)
我的环境: [root@localhost ~]# uname -r 2.6.32-642.el6.x86_64 [root@localhost ~]# cat /etc/redhat-release ...
- new操作符创建对象的四个步骤
new操作符创建对象可以分为以下四个步骤: 创建一个空对象 将所创建对象的__proto__属性值设为构造函数的prototype的属性值 执行构造函数中的代码,构造函数中的this指向该对象 返回对 ...