在单体应用时,不同业务模块部署在同一个JVM进程内,这时通过本地调用就可以解决不同业务模块之间的相互引用﹔但在多体应用时,不同业务模块大多部署到不同的机器上,这时一个高效、稳定的RPC框架就显得特别重要了。Apache Dubbo作为阿里巴巴开源的分布式RPC框架,是众多RPC框架中比较优秀的一个,在进入Apache孵化器项目后现已毕业,相信在开源社区的不断贡献下,它会成为RPC框架中的佼佼者。
为何要研究Apache Dubbo的实现原理
我们首先可以学习和深刻体会到分层架构带来的好处。Dubbo框架从整体上分为了业务(Business)层、RPC层和远程调用(Remoting〉层,其中业务层提供API,让使用者方便地发布与引用服务﹔RPC层则是对服务注册与发现、服务代理、路由、负载均衡等功能的封装,该层又可以被划分为很多层﹔远程调用层则是对网络传输与请求数据序列/反序列化等的抽象。使用分层架构可以保证下层的改变对上层不可见,并且可以实现关注点分离,比如使用者使用Dubbo时只关心如何使用业务层的API来发布与引用服务,而不需要关心RPC层的实现,当新版本 Dubbo升级了RPC层的逻辑时,使用者只需要升级Dubbo的版本就可以了,这是因为RPC层的修改对业务层使用者来说是透明的。
我们也可以学习到好的框架应该具有可扩展性。Dubbo就是一个扩展性极强的框架,其RPC层中的所有组件都是基于SPI扩展接口实现的,每个组件都可以被替换﹔Dubbo增强了JDK中提供的标准SPI功能,并且增加了对扩展接口的loC(一个扩展接口可以直接使用setter()方法注入其他扩展接口)和AOP 的支持(可以使用Wrapper类对扩展接口进行功能增强)﹔增强SPI不会一次性实例化扩展点的所有实现类,从而避免了当扩展点实现类初始化很耗时但当前还没用上它的功能时,仍进行加载实例化这种浪费资源的情况;增强的SPI是在具体用到某个实现类时才对具体实现类进行实例化。
如何阅读本书
第一部分基础篇
第一部分为基础篇,首先从整体上讲解使用Dubbo搭建的系统由哪些模块组成,各模块相互之间的调用关系是怎么样的,然后基于本书的Demo讲解如何使用Dubbo;
第1章Dubbo基础本章首先初步介绍了Dubbo中各个组件之间的关系,然后基于本书的Demo讲解了Dubbo 的基本使用方法,希望大家在使用ZooKeeper搭建起服务注册中心后,练习本书的Demo,以便对 Dubbo的使用有深入的理解。
第二部分高级篇
第二部分为高级篇,主要讲解Dubbo框架内部的实现原理,包含支撑Dubbo框架的适配器类原理、动态编译原理、增强SPI原理、消费端的泛化调用实现原理、消费端异步调用与服务提供端的异步执行、Dubbo框架的线程模型、消费端负载均衡策略、消费端集群容错策略、并发控制原理、Dubbo网络协议等﹔
第2章Dubbo框架内核原理剖析本章首先讲解了Dubbo框架的分层架构,除了最上面的两层,其他每层都是可以被替换的SPI组件,可知 Dubbo是一个扩展性极强的框架﹔然后讲解了Dubbo核心的适配器原理以及增强SPI原理;最后讲解了Dubbo是如何使用JavaAssist减少反射调用开销的。本章内容是Dubbo框架的内核原理实现,后面的章节我们会具体针对每个SPI组件进行讲解。
第3章远程服务发布与引用流程剖析本章首先详细讲解了Dubbo服务提供方启动的流程以及Dubbo 服务提供端如何对接收的请求进行处理,然后讲解了Dubbo服务消费方启动流程以及如何发起一次远程过程调用。学完本章,相信大家对Dubbo的服务发布与消费的流程将会有直观的理解。
第4章 Directory目录与Router路由服务本章首先讲解了RegistryDirectory在消费服务方是何时进行创建的,以及如何动态地根据服务注册中心推送的服务元数据来更新RegistryDirectory中维护的服务提供者信息、路由等信息的,然后讲解了消费端发起远程调用时如何从 RouterChain中获取经过路由规则过滤后的服务提供者的inovker列表。
第5章Dubbo消费端服务mock与服务降级策略原理本章首先讲解了Dubbo中如何对一个指定的服务进行服务降级,并讲解了在 Dubbo中如何实现服务降级﹔然后讲解了Dubbo消费端服务mock 原理,以及如何在服务消费端使用mock功能。
第6章 Dubbo集群容错与负载均衡策略本章主要探讨了Dubbo框架提供的各种集群容错策略以及实现原理,并讲解了当业务需要时如何基于SPI接口实现自己的集群容错策略,然后讲解了Dubbo框架提供的常用的负载均衡策略以及实现原理,并讲解了当业务需要时,如何基于SPI接口实现自己的负载均衡策略。
第7章Dubbo线程模型与线程池策略本章首先探讨了Dubbo框架提供的几种常见的线程模型以及实现原理,然后讲解了Dubbo提供的常用的几种线程池策略,并讲解了当业务需要定制线程池策略或者线程模型时,如何基于SPI接口进行定制。
第8章Dubbo如何实现泛化引用本章首先从服务消费端讲解了如何使用Filter链中的GenericImplFilter对三种泛化调用的参数进行合法性校验,然后讲解了服务提供端接受请求后如何使用Filter链中的GenericFilter对泛化请求进行处理。
第9章Dubbo并发控制本章首先探讨了Dubbo中消费端如何对并发请求数进行限制,可知当激活并发量达到指定值后,当前客户端请求线程会被挂起,并等待;如果等待超时了,则直接抛出异常,这时服务根本都没有发送到服务提供方服务器。然后,我们探讨了Dubbo中服务提供端如何对并发请求数进行限制,可知服务提供方在设置并发数量后,如果同时请求数量大于设置的executes 值,则会直接抛出异常。
第10章Dubbo隐式参数传递本章主要讲解了Dubbo 如何实现隐式参数传递,即为了实现隐式参数传递,首先需要在服务消费端的AbstractClusterInvoker类的invoke()方法内,把附加属性键值对放入RpcInvocation的 attachments变量中,然后经过网络传输到服务提供端;服务提供端则使用ContextFilter对请求进行拦截,并从RpcInvocation中获取 attachments中的键值对,接着使用RpcContext.getContext().setAttachment将键值对设置到上下文中,然后就可以在服务提供方服务实现类方法里使用RpcContext.getContext().getAttachment()方法获取参数值了。
第11章 Dubbo全链路异步本章主要讲解了Dubbo框架全链路异步实现,包含服务消费端如何实现异步调用、服务提供端如何实现异步执行、改造为异步后存在哪些问题以及这些问题如何进行解决等。
第12章本地服务暴露与引用原理本章主要讲解了Dubbo本地服务发布与引用的原理,可知本地导出使用了injvm 协议,这是一个伪协议,它不开启端口,不发起远程调用,只在JVM内直接关联,但执行Dubbo的 Filter链。
第13章Dubbo协议与网络传输本章首先探讨了Dubbo框架的协议帧格式,并讲解了服务消费端如何把发送的请求数据封装为Dubbo协议帧,并进行序列化处理,然后讲解了服务提供方如何解决半包粘包问题,以及如何把解码后的数据转换为POJO类对象。
第三部分实践篇
第三部分为实践篇,主要探讨如何使用Arthas和一些Demo来为研究Dubbo框架原理提供方便,并且讲解如何基于CompletableFuture和 Netty模拟RPC同步与纯异步调用。
第14章Dubbo实践本章主要探讨了如何使用Arthas 和一些 Demo来便捷地研究Dubbo框架的实现,并且基于CompletableFuture和 Netty模拟了RPC同步与纯异步调用。
这是一份在职淘宝的大佬纯手写的文档,需要获取的小伙伴可以直接转发+关注后私信(学习)或(资料)即可免费获取到!
网友评论