我所理解的 Dubbo



在公司实习这段时间,虽然知道公司是使用 Dubbo 来调用服务的,但是没有深入理解Dubbo的原理,以及为什么要使用 Dubbo,因此重新深入学习了 Dubbo,总结下:

1. 官方文档

Dubbo中文官方文档
感觉无论学习什么,看官方文档总是最最最深入学习知识的,另外,Dubbo的Github 地址:https://github.com/apache/incubator-dubbo

2.什么是Dubbo

Dubbo 是一款高性能、轻量级的开源Java RPC 框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。简单来说 Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。
RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。比如两个不同的服务 A、B 部署在两台不同的机器上,那么服务 A 如果想要调用服务 B 中的某个方法该怎么办呢?使用 HTTP请求 当然可以,但是可能会比较慢而且一些优化做的并不好。 RPC 的出现就是为了解决这个问题,现在明白了实习公司有些接口是调用其他平台的原因。

3.为什么要用 Dubbo?

  1. 把系统拆分成很多的服务,每个人负责一个服务,大家的代码都没有冲突,服务可以自治,自己选用什么技术都可以,每次发布如果就改动一个服务那就上线一个服务好了,不用所有人一起联调,每次发布都是几十万行代码,甚至几百万行代码了。
    可以参考why use dubbo

  2. 现在越来越多项目都是面向服务编程,即SOA,把工程按照业务逻辑拆分成服务层、表现层两个工程。服务层中包含业务逻辑,只需要对外提供服务即可。表现层只需要处理和页面的交互,业务逻辑都是调用服务层的服务来实现。SOA架构中有两个主要角色:服务提供者(Provider)和服务使用者(Consumer)。

如果你要开发分布式程序,你也可以直接基于 HTTP 接口进行通信,但是为什么要用 Dubbo呢?

  • 负载均衡——同一个服务部署在不同的机器时该调用那一台机器上的服务。
  • 服务调用链路生成——随着系统的发展,服务越来越多,服务间依赖关系变得错踪复杂,甚至分不清哪个应用要在哪个应用之前启动,架构师都不能完整的描述应用的架构关系。Dubbo 可以为我们解决服务之间互相是如何调用的。
  • 服务访问压力以及时长统计、资源调度和治理——基于访问压力实时管理集群容量,提高集群利用率。
  • 服务降级——某个服务挂掉之后调用备用服务。

4. Dubbo架构图

图片来自官方文档
在这里插入图片描述

  • 服务容器负责启动,加载,运行服务提供者。

  • 服务提供者在启动时,向注册中心注册自己提供的服务。

  • 服务消费者在启动时,向注册中心订阅自己所需的服务。

  • 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送 变更数据给消费者。

  • 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。

  • 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

    5. Dubbo工作原理及流程

    在这里插入图片描述
    图中从下至上分为十层,各层均为单向依赖,右边的黑色箭头代表层之间的依赖关系,每一层都可以剥离上层被复用,其中,Service 和 Config 层为 API,其它各层均为 SPI。

  • 第一层:service层,接口层,给服务提供者和消费者来实现的

  • 第二层:config层,配置层,主要是对dubbo进行各种配置的

  • 第三层:proxy层,服务接口透明代理,生成服务的客户端 Stub 和服务器端 Skeleton

  • 第四层:registry层,服务注册层,负责服务的注册与发现

  • 第五层:cluster层,集群层,封装多个服务提供者的路由以及负载均衡,将多个实例组合成一个服务

  • 第六层:monitor层,监控层,对rpc接口的调用次数和调用时间进行监控

  • 第七层:protocol层,远程调用层,封装rpc调用

  • 第八层:exchange层,信息交换层,封装请求响应模式,同步转异步

  • 第九层:transport层,网络传输层,抽象mina和netty为统一接口

  • 第十层:serialize层,数据序列化层,网络传输需要

工作流程:
第一步:provider 向注册中心去注册
第二步:consumer 从注册中心订阅服务,注册中心会通知 consumer 注册好的服务
第三步:consumer 调用 provider
第四步:consumer 和 provider 都异步通知监控中心

注册中心挂了可以继续通信,因为刚开始初始化的时候,消费者会将提供者的地址等信息拉取到本地缓存,所以注册中心挂了可以继续通信。

6.Dubbo的负载均衡策略

  • random loadbalance
    默认情况下,dubbo 是 random load balance ,即随机调用实现负载均衡,可以对 provider 不同实例设置不同的权重,会按照权重来负载均衡,权重越大分配流量越高,一般就用这个默认的就可以了。
  • roundrobin loadbalance
    这个的话默认就是均匀地将流量打到各个机器上去,但是如果各个机器的性能不一样,容易导致性能差的机器负载过高。所以此时需要调整权重,让性能差的机器承载权重小一些,流量少一些。
  • leastactive loadbalance
    这个就是自动感知一下,如果某个机器性能越差,那么接收的请求越少,越不活跃,此时就会给不活跃的性能差的机器更少的请求。

  • consistanthash loadbalance
    一致性 Hash 算法,相同参数的请求一定分发到一个 provider 上去,provider 挂掉的时候,会基于虚拟节点均匀分配剩余的流量,抖动不会太大。如果你需要的不是随机负载均衡,是要一类请求都到一个节点,那就走这个一致性 Hash 策略。

7.Dubbo 集群容错策略

ailover cluster 模式
失败自动切换,自动重试其他机器,默认就是这个,常见于读操作。(失败重试其它机器)

可以通过以下几种方式配置重试次数:

<dubbo:service retries="2" />

或者

<dubbo:reference retries="2" />

或者

<dubbo:reference>
    <dubbo:method name="findFoo" retries="2" />
</dubbo:reference>

failfast cluster 模式
一次调用失败就立即失败,常见于非幂等性的写操作,比如新增一条记录(调用失败就立即失败)

failsafe cluster 模式
出现异常时忽略掉,常用于不重要的接口调用,比如记录日志。

配置示例如下:

<dubbo:service cluster="failsafe" />

或者

<dubbo:reference cluster="failsafe" />

failback cluster 模式
失败了后台自动记录请求,然后定时重发,比较适合于写消息队列这种。

forking cluster 模式
并行调用多个 provider,只要一个成功就立即返回。常用于实时性要求比较高的读操作,但是会浪费更多的服务资源,可通过 forks=”2” 来设置最大并行数。

broadcacst cluster
逐个调用所有的 provider。任何一个 provider 出错则报错(从2.1.0 版本开始支持)。通常用于通知所有提供者更新缓存或日志等本地资源信息。

8.zookeeper宕机与dubbo直连的情况

zk经常作为Dubbo 的注册中心,zk后面也会继续深入学习。。
在实际生产中,假如zookeeper注册中心宕掉,一段时间内服务消费方还是能够调用提供方的服务的,实际上它使用的本地缓存进行通讯,这只是dubbo健壮性的一种提现。

dubbo的健壮性表现:

  • 监控中心宕掉不影响使用,只是丢失部分采样数据
  • 数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务
  • 注册中心对等集群,任意一台宕掉后,将自动切换到另一台
  • 注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯
  • 服务提供者无状态,任意一台宕掉后,不影响使用
  • 服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复

注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小。所以,我们可以完全可以绕过注册中心——采用 dubbo 直连 ,即在服务消费方配置服务提供方的位置信息。

<dubbo:reference id="userService" interface="com.zzt.malll.service.UserService" url="dubbo://localhost:20880"

9.其他问题

以上就是我对 Dubbo 的入门总结,多总结,多回来看,知识才会一直记得,以后有时间抽空继续写博客hhhhh。


   转载规则


《我所理解的 Dubbo》 ForeverSen 采用 知识共享署名 4.0 国际许可协议 进行许可。
 上一篇
LeetCode中位运算相关题目 LeetCode中位运算相关题目
这阶段刷完了 LeetCode 上有关位运算的题目,感觉位运算还是挺难,很难get到点,有空还是要去加强学习,要掌握 与&、异或^、或|、非~,还有算术左移、算术右移、无符号右移 。还有 Java 中 Integer 类中常见位运
2019-06-25
下一篇 
计算机网络知识总结 计算机网络知识总结
 最近这两星期抽空来看看计算机网络相关的知识,虽然大三上学期有学这门课,但是很快就忘了,记忆不是很深,现在再重温一下。 计算机网络概述: 通信:计算机通信是计算机中进程(即运行着的程序)之间的通信。计算机网络采用的通信方式是客户-服务器方
  目录