1)Dubbox简介
Dubbox是一个分布式服务框架,其前身是阿里巴巴开源项目dubbo,被国内电商及互联网项目中使用,后期阿里巴巴停止了对该项目的维护,当当网便在此基础上进行优化,为了和原有的dubbo进行区分,故将其命名为dubbox。
Dubbox致力于提供高性能和透明化的rpc远程调用服务方案以及 SOA 服务治理方案。简单的说,dubbox 就是个服务框架,如果没有分布式的需求,其实是不需要用的,只有在分布式的时候,才有 dubbox 这样的分布式服务框架的需求,说白了就是个远程服务调用的分布式框架。
前面我们刚刚说了SOA架构的话,服务之间通信采用RPC远程调用技术,而dubbo说白了就是一个RPC框架。
RPC框架有很多,有dubbo、gRPC、Thrift、HSF等等
我们先看看什么是RPC以及RPC调用过程。在这之前,我们写一个普通java类,new一个类的对象出来,然后调用它的方法,这个就是本地函数调用,因为是在同一个地址空间。
在分布式应用中,很多功能都是单独被拎出来了,你单独的把它放在一个服务里面,让别的服务去调用它。
所以RPC它是一种进程间的通信方式。
RPC允许程序调用另一个地址空间的过程或函数。
RPC的两个核心模块是:通讯和序列化
2)Dubbo工作原理
dubbo 是目前事实上大部分公司的分布式系统的 rpc 框架标准,基于 dubbo 也可以构建一整套的微服务架构。但是需要自己大量开发。。
Dubbo的总体架构,如图所示:
第一层:service 层,接口层,给服务提供者和消费者来实现的
第二层:config 层,配置层,主要是对 dubbo 进行各种配置的
第三层:proxy 层,服务代理层,无论是 consumer 还是 provider,dubbo 都会给你生成代理,代理之间进行网络通信
第四层:registry 层,服务注册层,负责服务的注册与发现
第五层:cluster 层,集群层,封装多个服务提供者的路由以及负载均衡,将多个实例组合成一个服务
第六层:monitor 层,监控层,对 rpc 接口的调用次数和调用时间进行监控
第七层:protocal 层,远程调用层,封装 rpc 调用
第八层:exchange 层,信息交换层,封装请求响应模式,同步转异步
第九层:transport 层,网络传输层,抽象 mina 和 netty 为统一接口
第十层:serialize 层,数据序列化层
3)Dubbo工作流程
节点角色说明:
Provider: 暴露服务的服务提供方。
Consumer: 调用远程服务的服务消费方。
Registry: 服务注册与发现的注册中心。
Monitor: 统计服务的调用次数和调用时间的监控中心。
Container: 服务运行容器。
调用关系说明:
1、dubbox首先有一个container作为启动容器,负责加载和运行服务提供者。
2、服务启动之后,服务提供者(service provider)会向注册中心(registry)注册服务地址,我们可以在配置文件中配置具体的服务端口号。
3、服务消费(service consumer)者会向注册中心(registry)订阅自己的服务。
4、注册中心返回服务提供者的注册列表给消费者,如果有变更,那么注册中心将会基于长连接发送给消费者
5、服务消费者,会从服务提供者的地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,就换一台进行调用
6、服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
4)注册中心 Zookeeper介绍
官方推荐使用 zookeeper 注册中心。注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小。
Zookeeper 是 Apacahe Hadoop 的子项目,是一个树型的目录服务,支持变更推送,适合作为 Dubbox 服务的注册中心,工业强度较高,可用于生产环境。
问题:注册中心挂了可以继续通信吗?
答:可以,因为刚开始初始化的时候,消费者会将提供者的地址等信息拉取到本地缓存,所以注册中心挂了可以继续通信。
5)dubbo支持的通讯协议
序列化与反序列化是实现远程通讯的核心模块。
序列化,就是把数据结构或者是一些对象,转换为二进制串的过程,而反序列化是将在序列化过程中所生成的二进制串转换成数据结构或者对象的过程。
dubbo 支持 hession、Java 二进制序列化、json、SOAP 文本序列化多种序列化协议。但是 hessian 是其默认的序列化协议。Dubbo支持以下几种通讯协议
5.1 dubbo协议
默认就是走 dubbo 协议,单一长连接,进行的是 NIO 异步通信,基于 hessian 作为序列化协议。使用的场景是:传输数据量小(每次请求在 100kb 以内),但是并发量很高。
为了要支持高并发场景,一般是服务提供者就几台机器,但是服务消费者有上百台,可能每天调用量达到上亿次!此时用长连接是最合适的,就是跟每个服务消费者维持一个长连接就可以,可能总共就 100 个连接。然后后面直接基于长连接 NIO 异步通信,可以支撑高并发请求。
长连接,通俗点说,就是建立连接过后可以持续发送请求,无须再建立连接。
而短连接,每次要发送请求之前,需要先重新建立一次连接。
5.2 rmi协议
走 Java 二进制序列化,多个短连接,适合消费者和提供者数量差不多的情况,适用于文件的传输,一般较少用。
5.3 hessian协议
走 hessian 序列化协议,多个短连接,适用于提供者数量比消费者数量还多的情况,适用于文件的传输,一般较少用。
5.4 http协议
走 json 序列化。
5.5 webservice
走 SOAP 文本序列化。
6)dubbo负载均衡策略
6.1 random loadbalance
默认情况下,dubbo 是 random load balance ,即随机调用实现负载均衡,可以对 provider 不同实例设置不同的权重,会按照权重来负载均衡,权重越大分配流量越高,一般就用这个默认的就可以了。
6.2 roundrobin loadbalance
这个的话默认就是均匀地将流量打到各个机器上去,但是如果各个机器的性能不一样,容易导致性能差的机器负载过高。所以此时需要调整权重,让性能差的机器承载权重小一些,流量少一些。
举个栗子。跟运维同学申请机器,有的时候,我们运气好,正好公司资源比较充足,刚刚有一批热气腾腾、刚刚做好的虚拟机新鲜出炉,配置都比较高:8 核 + 16G 机器,申请到 2 台。过了一段时间,我们感觉 2 台机器有点不太够,我就去找运维同学说,“哥儿们,你能不能再给我一台机器”,但是这时只剩下一台 4 核 + 8G 的机器。我要还是得要。
这个时候,可以给两台 8 核 16G 的机器设置权重 4,给剩余 1 台 4 核 8G 的机器设置权重 2。
6.3 leastactive loadbalance
这个就是自动感知一下,如果某个机器性能越差,那么接收的请求越少,越不活跃,此时就会给不活跃的性能差的机器更少的请求。
6.4 consistanthash loadbalance
一致性 Hash 算法,相同参数的请求一定分发到一个 provider 上去,provider 挂掉的时候,会基于虚拟节点均匀分配剩余的流量,抖动不会太大。如果你需要的不是随机负载均衡,是要一类请求都到一个节点,那就走这个一致性 Hash 策略。