绝无仅有!阿里P8专家整理分享的深度剖析ApacheDubbo核
Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合)。从服务模型的角度来看,Dubbo采用的是一种非常简单的模型,要么是提供方提供服务,要么是消费方消费服务,所以基于这一点可以抽象出服务提供方(Provider)和服务消费方(Consumer)两个角色。
Dubbo框架设计一共划分了10个层,而最上面的Service层是留给实际想要使用Dubbo开发分布式服务的开发者实现业务逻辑的接口层。图中左边淡蓝背景的为服务消费方使用的接口,右边淡绿色背景的为服务提供方使用的接口, 位于中轴线上的为双方都用到的接口。
通过研究Dubbo框架的实现原理,我们到底能学到什么?
作为高可用分布式 RPC 框架,其自身必须具有容错能力,以便提高系统的可用性。Dubbo 框架则提供了分布式系统中常见的集群容错策略,并且提供了扩展接口,让使用方便地定制自己的集群容错策略,通过研究 Dubbo 框架提供的集群容错策略,可以让我们对分布式系统中的容错技术有深入的理解。
研究透彻dubbo框架原理实现后,你会对分布式系统中的很多技术点有深入的理解。分布式系统是应用的发展方向,因为随着业务规模的增大,为了保障系统的可伸缩性、高可用性,系统必然朝着分布式方向发展。所以,掌握一些分布式系统中的优秀RPC框架的原理及实现细节,无论现在还是将来都将成为区别于他人的核心竞争力。
今天就给大家分享阿里P8高级技术专家分享出的深度剖析ApacheDubbo核心技术文档,将从目录、主要内容和总结给大家来进行介绍,因为文档包含的内容较多,不能一一给大家做介绍,所以只能把部分知识点拿出来给大家介绍,希望大家能够理解与喜欢!!
Dubbo基础;
1.1初识Dubbo,整体来说,一个公司业务系统的演进流程基本上都是从单体应用到多体应用。业务系统为单体应用时,不同业务模块的相互调用直接在本地JVM进程内就可以完成;而变为多个应用时,相互之间进行通信的方式就不是简单地进行本地调用了,因为不同的业务模块部署到了不同的JVM进程里,更常见的情况是部署到了不同的机器中,这时候,一个高效稳定的RPC远程调用框架就变得非常重要。
Dubbo是阿里巴巴开发的一个开源的高性能的RPC调用框架,是一个致力于提供高性能和透明化的RPC远程调用服务解决方案。作为阿里巴巴SOA服务化治理方案的核心框架,目前它已从Apache孵化器项目毕业,其前景可谓无限光明。
1.2本文Demo详解;
Dubbo框架内核原理剖析;
2.1 Dubbo分层架构概述,本节我 从整体上来看看 Dubbo 的分层架构设计,架构分 个比较经典的模式,比如网络中的 协议,每层执行固定的功能,上层依赖下 提供的功能,下层的改变对上层不可见 ,并且每层都是 个可被替换的组件
2.2 Dubbo远程调用细节,本节我们先从整体来看看 Dubbo 务发布与消费的概要流程, 以便对其中涉及的概念有个了解,更详细的过程后面的章节会具体讲解。
2.3 Dubbo的适配器原理,在前面谈论 ubbo 分层架构时,我们讲到, Dubbo 为每个功能点提供了一个 SPI展接口, Dubbo 框架在使用扩展点功能的时候是对接口进行依赖的,而 个扩展接口对应系列的扩展实现类。那么如何选择使用哪个扩展接口的实现类呢?其实这是使用适配器模式来做的。
2.4 Dubbo的动态编译原理,众所周知 Java 程序要想运行首先需要使用 javac 源代码编译为 class 宇节码文件然后使用 M 把 class 字节码文件加载到内存创建 lass 对象后,使用 lass 对象 建对象实例。正常情况下我 是把所有源文件静态编译为字节码文件, 然后由 NM 统一加载,而动态编译则是在 JVM 进程运行时把源文件编译为字节码 文件,然后使用字节码文件创建对象实例。
2.5 Dubbo增强SPI,前面我们讲解了 Dubbo 框架如何使用动态编译技术给每个扩展接 生成适配器类,并讲解了适配器类根据其中的参数来选择对应的 SPI 实现,下面我们讲解在适配器类中是如何根据参数来装载具体的SPI 实现的。
2.6 Dubbo使用JavaAssist减少反射调用开销,Dubbo 会给 个服务提供者的实现类生产一个 Wrapper 这个 Wrapper 类里面最终调用服务提供者的接口实现类,Wrapper 类的存在是为了减少反射的调用。当服务提供方收到消费方发来的请求后,需要根据消费者传递过来的方法名和参数反射调用服务提供者的实现类,而反射本身是有性能开销的,Dubbo把每个服务提供者的实现类通过JavaAssist包装为- - 个Wrapper 类以减少反射调用开销。那么Wrapper类为何能减少反射调用呢?
远程服务发布与引用流程剖析;
3.1 Dubbo服务发布端启动流程剖析,
3.2 Dubbo服务提供方如何处理请求,
3.3 Dubbo服务消费方启动流程剖析,
3.4 Dubbo服务消费端一次远程调用过程,
Directory目录与Router路由服务;
4.1 Directory目录.,本章我们主要从下面几个方面来探讨RegistryDirectory :●消费端启动时何时构建RegistryDirectory;●RegistryDirectory 管理的invoker列表如何动态变化;●路由信息是如何保存与变化的。
4.2 RegistryDirectory 的创建;
4.3 RegistryDirectory 中invoker列表的更新,上一节探讨了RegistryDirectory 何时被创建,本节我们看看其管理的invoker列表是何时被创建与更新的。
Dubbo消费端服务mock与服务降级策略原理;
5.1服务降级原理,
5.2本地服务mock原理,
Dubbo集群容错与负载均衡策略;
6.1 Dubbo集群容错策略概述,当我 进行系统设计时 不仅要考虑正常情况 代码逻辑应该如何 还要考虑异常情况下代码逻辑应该怎么走。当服务消费方调用服务提供方的服务 现错误 Dubbo供了多种容错方案 默认模式为 Failo er luster ,也就是失败重试。
6.2 Failfast Cluster策略源码分析;
6.3 Failsafe Cluster策略源码分析;
6.4 Failover Cluster策略源码分析;
6.5 Failback Cluster策略源码分析;
6.6 Forking Cluster策略源码分析;
6.7 Broadcast Cluster策略源码分析;
6.8如何基于扩展接口自定义集群容错策略,前面已经讲过 Dubbo 本身提供了丰富的集群容错策略,但是如果你有定制化需求可以根据 Dubbo 提供的扩展接口Cluster进行定制;
6.9 Dubbo负载均衡策略概述,当服务提供方是集群时,为了避免大量请求一直集中在一个或者几个服务提供方机器上,从而使这些机器负载很高,甚至导致服务不可用,需要做一定的负载均衡策略。Dubbo提供了多种均衡策略,默认为random,也就是每次随机调用一台服务提供者的服务。
6.10 Random LoadBalance策略源码分析;
6.11 RoundRobin LoadBalance策略源码分析;
6.12 LeastActive LoadBalance策略源码分析;
6.13 ConsistentHash LoadBalance策略源码分析;
6.14如何基于打展接口自定义负载均衡策略,如前所述,Dubbo 本身提供了丰富的负载均衡策略,但是如果你有定制化需求,则可以根据Dubbo提供的扩展接口LoadBalance进行定制。
Dubbo线程模型与线程池策略;
7.1 Dubbo的线程模型概述,Dubbo默认的底层网络通信使用的是Netty,服务提供方NettyServer使用两级线程池,其中EventLoopGroup(boss) 主要用来接收客户端的链接请求,并把完成TCP三次握手的连接分发给EventLoopGroup(worker)来处理,我们把boss和worker线程组称为IO线程。
7.2 AllDispatcher源码剖析;
7.3 DirectDispatcher源码剖析;
7.4 MessageOnlyDispatcher源码剖析;
7.5 ExecutionDispatcher源码剖析;
7.6 ConnectionOrderedDispatcher源码剖析;
7.7线程模型的确定时机;
7.8如何基于扩展接口自定义线程模型,Dubbo提供了常用的线程模型,这些模型可以满足我们绝大部分的需求,但是也可以根据自己的需要进行扩展定制。
7.9 Dubbo的线程池策略,我们在上面讲解Dubbo线程模型时提到,为了尽量早地释放Netty的I/O线程,某些线程模型会把请求投递到线程池进行异步处理,那么这里所谓的线程池是什么样的线程池呢?其实这里的线程池ThreadPool也是一个扩展接口SPI,Dubbo 提供了该扩展接口的一些实现。
7.10 FixedThreadPool源码剖析;
7.11 LimitedThreadPool源码剖析;
7.12 EagerThreadPool源码剖析;
7.13 CachedThreadPool源码剖析;
7.14线程池的确定时机;
7.15如何基于扩展接口自定义线程池策略,Dubbo提供了常用的线程池策略,这些策略可以满足我们绝大部分的需求,但是也可以根据自己的需要进行扩展定制。
Dubbo如何实现泛化引用;
我们在本章中将探讨Dubbo如何实现泛化调用,主要内容包括:服务消费端如何使用GenericImplFiter拦截泛化调用,把泛化参数进行校验并发起远程调用;服务提供方如何使用GenercFilter拦截请求,并把泛化参数进行反序列化处理,然后把请求转发给具体的服务进行执行。
8.1服务消费端GenericlmplFilter源码分析;
8.2服务提供端GenericFilter源码分析;
Dubbo并发控制;
由于资源的限制, 般会在服务提供方和消费方限制接口调用 并发数,本章将探讨相关的原理。
9.1服务消费端并发控制;
9.2服务提供端并发控制;
Dubbo隐式参数传递;
AbstractClusterInvoker是服务集群容错策略的抽象类,在默认情况下,集群容错策略为FailoverClusterlnvoker,其继承了AbstractCluterInvoker。
10.1服务消费端AbstractClusterlnvoker原理剖析
10.2服务提供方ContextFilter原理剖析
Dubbo全链路异步;
11.1服务消费端异步调用,异步调用是基于NIO的非阻塞能力实现并行调用,服务消费端不需要启动多线程即可完成并行调用多个远程服务,相对多线程开销较小。
11.2服务提供端异步执行,在Provider端非异步执行时,对调用方发来的请求的处理是在Dubbo内部线程模型的线程池里的线程中执行的。 在Dubbo中,服务提供方提供的所有服务接口都是使用这一个线程池来执行的,所以当一个服务执行比较耗时时,可能会占用线程池中很多线程,从而导致其他服务的处理收到影响。
Provider端异步执行则将服务的处理逻辑从Dubbo内部线程池切换到业务自定义线程,避免Dubbo线程池中的线程被过度占用,有助于避免不同服务间的互相影响。但需要注意的是,Provider端异步执行对节省资源和提升RPC响应性能是没有效果的,这是因为如果服务处理比较耗时,虽然不是使用Dubbo框架内部线程处理,但还是需要业务自己的线程来处理,另外还有副作用,即会新增一次线程上下文切换(从Dubbo内部线程池线程切换到业务线程)。
11.3异步调用与执行引入的新问题;
本地服务暴露与引用原理;
12.1 本地服务暴露流程,
12.2本地服务引|用启动流程,如果在消费端没有指定scope类型,则启动时会检查当前JVM内是否有导出的服务,如果有则自动开启本地引用(也就是将协议类型修改为injvm)。
12.3本地服务一次引用流程,上面两节我们分别讲解了本地服务如何暴露、本地服务引用的启动流程,本节我们介绍一下发起一次本地引用调用的流程。
Dubbo协议与网络传输;
在前面的章节中,我们介绍了服务消费端远程服务调用流程与服务提供端远程服务处理流程,但还有一些东西是我们没有提到的,比如服务消费端如何把服务请求信息序列化为二进制数据、服务提供方如何把消费端发送的二进制数据反序列化为可识别的POJO对象、Dubbo的应用层协议是怎么样的,等等。本章我们就来介绍相关的内容。
13.1 Dubbo协议,
13.2服务消费方编码原理
13.3服务发布方解码原理
Dubbo实践;
14.1 Arthas的简介与安装;
14.2查扩展接口适配器类的源码;
14.3查服务提供端Wrapper类的源码;
14.4查询Dubbo启动后都有哪些Filter,在Dubbo中,Filter链是一个亮点,通过Filter链可以对服务请求和服务处理流程进行干预,有时候我们想要知道运行时到底有哪些Filter在工作,这时使用Arthas的trace命令显得比较重要。
14.5 Demo验证RoundRobin LoadBalance负载均衡原理;
14.6如何动态获取Dubbo服务提供方地址列表;
14.7根据IP动态路由调用Dubbo服务;前面我们探讨了如何获取某一个Dubbo服务的提供者列表,本节我们探讨如何使用Dubbo的扩展,实现指定IP调用;
14.8基于CompletableFuture和Netty模拟RPC同步与纯异步调用,Dubbo的服务消费端基于CompletableFuture实现了纯异步调用,其实还不单单是CompletableFuture的功劳,归根到底是Netty的NIO非阻塞功能提供的底层实现,本节我们就基于CompletableFuture和Netty来模拟一下如何异步发起远程调用,以便加深对Dubbo异步调用实现原理的理解。
这份【深度剖析ApacheDubbo核心技术内幕】文档共有288页,需要完整版的小伙伴,可以转发此文关注小编,点此处来获取!!