认识Dubbo与RPC

简介: 大家好,我是王有志。今天开个新坑,和大家一起学习Dubbo。我们从一些基本的概念开始,然后和大家一起学习Dubbo的使用,最后深入Dubbo的核心原理。

关注王有志,分享硬核Java技术的互金摸鱼侠
加入Java人的提桶跑路群共同富裕的Java人

开个新坑,和大家一起学习Dubbo 3.X。我们按照一个由浅入深顺序来学习,先从使用Dubbo开始,再深入Dubbo的核心原理。

今天我们就从认识Dubbo开始,整体的内容可以分为3个部分:

  • Dubbo是什么

  • RPC是什么

  • Dubbo的架构

正式开始前我先叠个甲,通常网上很多资料将RPC称之为协议,并将RPC与HTTP进行比较,目前来看这已经成为“不太正确”但主流的说法了。而我个人是个原教旨主义者,更倾向使用RPC原初的解释,因此可能和你看到的部分文章有一定的差别。另外,因个人能力有限,若出现错误希望大家不吝赐教。

Tips:RPC的章节主要参考Andrew D. Birrell与Bruce Jay Nelson于1984年发表的论文《Implementing Remote Procedure Calls》,通常认为这篇文章是“现代”RPC的起源(实际上,1976年就有文献开始讨论RPC了)。

Dubbo是什么?

我们来看Apache Dubbo社区是怎样描述Dubbo的:

Apache Dubbo是一款RPC服务开发框架,用于解决微服务架构下的服务治理与通信问题,官方提供了Java、Golang等多语言SDK实现。使用Dubbo开发的微服务原生具备相互之间的远程地址发现与通信能力, 利用Dubbo提供的丰富服务治理特性,可以实现诸如服务发现、负载均衡、流量调度等服务治理诉求。Dubbo被设计为高度可扩展,用户可以方便的实现流量拦截、选址的各种定制逻辑。

Dubbo是具有高性能,可拓展等特性的RPC框架,除此之外,Dubbo还提供了服务治理的能力。

图1:Dubbo的能力.png

Dubbo的“野心”不仅仅在于提供一套完整的RPC调用及服务治理框架,更是将Dubbo与编程语言解绑,提供了大部分主流语言的版本。

Tips:该图截自Apache Dubbo社区在B站上发布的《5分钟快速了解Apache Dubbo》。

RPC是什么?

既然Dubbo的本质是RPC框架,那么在继续深入学习Dubbo前,我们有必要先来了解下RPC是什么。

RPC(Remote Procedure Call),即远程过程调用。《Implementing Remote Procedure Calls》中是这么解释的:

The idea of remote procedure calls (hereinafter called RPC) is quite simple. It is based on the observation that procedure calls are a well-known and well-understood mechanism for transfer of control and data within a program running on a single computer.Therefore, it is proposed that this same mechanism be
extended to provide for transfer of control and data across a communication network.

RPC的思想是基于对单机程序中的传输和处理数据的过程调用的观察,并建议将相同的机制拓展到远程网络通信上的结果。

是不是有点难理解?没关系,我们换一个简单点的说法,来看Sahn Lam在油管视频《What is RPC? gRPC Introduction》中的解释,视频中他通过本地过程调用与远程过程调用的对比进行解释:

A local procedure call is a function call within a process to execute some code.A remote procedure call enables one machine to invoke some code on another machine as if it is a local fuction call from a user's perspective.

这个解释就非常清晰了,RPC的核心是希望远程调用可以像本地函数调用一样简单。Birrell与Nelson正是基于此目标,给出了RPC服务的设计参考:

图2:PRC系统的设计.png

Birrell与Nelson的设计是基于存根(stub,即图中的User-stub和Server-stub)这个概念的,系统整体包含5个部分:

  • 用户端,服务调用方;

  • 用户端存根,保存函数声明,负责请求参数的打包与响应参数的解包;

  • RPC Runtime,选择合适的方式(协议)传输数据;

  • 服务端存根,保存函数声明,负责请求参数的解包与响应参数的打包;

  • 服务端,服务提供方。

用户端和服务端的开发者只需要从存根中获取并调用目标函数,而无需考虑目标函数所在服务器的地址和传输数据的方式,是非常契合“远程调用可以像本地函数调用一样简单”这样的愿景的。

好了,到这里我们已经对“原教旨主义”的RPC有了整体的认知,现在来回答一个不太“正经”的问题:既然有了HTTP为什么还要RPC?

这是个挺常见的初学误区,将RPC与HTTP划上了等号。首先RPC是一种思想(我觉得更像是简化远程服务调用的目标),而HTTP是应用层的传输协议,上图中“两个”RPC Runtime传输数据时可以使用HTTP,也可以是其它能够完成数据传输的方式。其次,“现代”RPC的理论诞生于1984年,而HTTP是1989年发起的,因此这个问题反过来问还显得稍微合理些。最后,HTTP的诞生的目的是接收和发布HTML页面,即在浏览器与服务端之间进行数据的传输,而不是应用在两个服务端之间的数据传输。

Tips

  • Sahn Lam和Alex Xu是油管频道ByteByteGo的管理者,拥有有43万粉丝,另外他们也是《System Design Interview》的作者;

  • RPC的系统设计图截自《Implementing Remote Procedure Calls》;

  • 实际的项目中,没有严格的用户端与服务端的区分,服务都可以提供对外的接口,也可以使用外部服务的接口。

Dubbo的架构

Dubbo 3.0开始,Dubbo的官方文档使用了新的抽象架构:

图3:Dubbo的架构.png

将Dubbo从整体划分了两层:

  • Dubbo数据面:提供RPC功能的核心部分,通过RPC协议进行通信,定义了调用规范,完成了数据交互的编码和解码功能做;

  • 服务治理控制面:服务治理的抽象,包含了注册中心,流量管控策略,Dubbo Admin控制台等。

Dubbo 3.0之前,官方给出过一张非常复杂的Dubbo 2.X的设计图(以下的部分是官方原文):

图4:Dubbo的分层架构.jpg

图例说明

  • 图中左边淡蓝背景的为服务消费方使用的接口,右边淡绿色背景的为服务提供方使用的接口,位于中轴线上的为双方都用到的接口;

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

  • 图中绿色小块的为扩展接口,蓝色小块为实现类,图中只显示用于关联各层的实现类;

  • 图中蓝色虚线为初始化过程,即启动时组装链,红色实线为方法调用过程,即运行时调时链,紫色三角箭头为继承,可以把子类看作父类的同一个节点,线上的文字为调用的方法。

Dubbo提供了非常丰富的接口,这些都是Dubbo的可被用户自定义的拓展点。Dubbo自身也采用了Microkernel+Plugin(微内核+拓展)的模式,Microkernel只负责组装Dubbo对Plugin的默认实现。

各层说明

  • config配置层:对外配置接口,以ServiceConfigReferenceConfig为中心,可以直接初始化配置类,也可以通过Spring解析配置生成配置类

  • proxy服务代理层:服务接口透明代理,生成服务的客户端Stub和服务器端Skeleton, 以ServiceProxy为中心,扩展接口为ProxyFactory

  • registry注册中心层:封装服务地址的注册与发现,以服务URL为中心,扩展接口为RegistryFactoryRegistryRegistryService

  • cluster路由层:封装多个提供者的路由及负载均衡,并桥接注册中心,以Invoker为中心,扩展接口为ClusterDirectoryRouterLoadBalance

  • monitor监控层:RPC调用次数和调用时间监控,以Statistics为中心,扩展接口为MonitorFactoryMonitorMonitorService

  • protocol远程调用层:封装RPC调用,以InvocationResult为中心,扩展接口为ProtocolInvokerExporter

  • exchange信息交换层:封装请求响应模式,同步转异步,以RequestResponse为中心,扩展接口为ExchangerExchangeChannelExchangeClientExchangeServer

  • transport网络传输层:抽象Mina和Netty为统一接口,以Message为中心,扩展接口为ChannelTransporterClientServerCodec

  • serialize数据序列化层:可复用的一些工具,扩展接口为SerializationObjectInputObjectOutputThreadPool

有些文章会将Service纳入Dubbo的层级结构中,但实际上Service是用户业务逻辑的部分,严格意义上并不是Dubbo自身的组成。

支持协议

协议是RPC框架的核心功能,定义了数据的传输格式,除了数据本身外,还应包含控制信息,如:序列化方式,超时时间等。

Dubbo支持了非常多的协议,在这里我将它们分成5类:

图5:Dubbo支持的协议.png

不要看到Dubbo支持了这么多协议就害怕,它虽然支持的多,但我们不必每个协议都深入。未来我们在学习到协议的部分是,会重点的学习Dubbo协议,Dubbo 3.X主推的Triple协议以及支持HTTP/2的gRPC,其余协议我们大致了解其特性即可。

Tips:实际上Dubbo 2.X的官方文档中有非常详细的设计文档,不知道为什么Dubbo 3.0中删除了这部分内容。

结语

好了,到目前为止希望你能够建立起一个对Dubbo设计的整体认知。设计虽然复杂,支持的协议虽然很多,但我们今天的目的不是“一文弄懂”。我们以理解RPC和Birrell与Nelson给出的设计为主,其次我们需要建立对Dubbo的设计的整体认知,看看它Dubbo在Birrell与Nelson的基础上做出了哪些拓展。如果有兴趣的话,可以参考Birrell与Nelson给出的架构来设计自己的RPC服务,需要考虑如何将服务保存到存根中?使用哪种方式进行交互?交互的数据结构该如何设计?

下一篇,我们一起来使用Duubbo,掌握Dubbo的应用。如果本文对你有帮助的话,请多多点赞支持。最后欢迎大家关注分享硬核技术的金融摸鱼侠王有志,我们下次再见!

目录
相关文章
|
2月前
|
负载均衡 Dubbo Java
Dubbo 3.x:探索阿里巴巴的开源RPC框架新技术
随着微服务架构的兴起,远程过程调用(RPC)框架成为了关键组件。Dubbo,作为阿里巴巴的开源RPC框架,已经演进到了3.x版本,带来了许多新特性和技术改进。本文将探讨Dubbo 3.x中的一些最新技术,包括服务注册与发现、负载均衡、服务治理等,并通过代码示例展示其使用方式。
80 9
|
7月前
|
编解码 Dubbo 应用服务中间件
Alibaba开源Dubbo源码解析手册,竟引领出RPC的新潮流
前言 Apache Dubbo,一款由阿里巴巴于2011年开源的高性能Java RPC框架,自开源以来在业界产生了深远影响。有大量公司广泛使用,甚至很多公司的自研RPC框架中都能看到Dubbo的影子。Dubbo在国内服务化体系演进过程中扮演了重要角色。尽管经历了几年的沉寂,但在阿里巴巴重启对Dubbo的开源维护,Dubbo正在从微服务领域的高性能RPC框架逐步演变为一个完整的微服务生态。 对于开发者来说,深入了解Dubbo底层的架构设计和实现是一项挑战。因此,一份完整的、体系化的对Apache Dubbo进行深入原理剖析的手册就显得尤为重要。
|
7月前
|
消息中间件 负载均衡 Dubbo
如何自己设计一个类似Dubbo的RPC框架?
如何自己设计一个类似Dubbo的RPC框架?
60 0
|
30天前
|
Java fastjson 数据安全/隐私保护
【Dubbo3技术专题】「云原生微服务开发实战」 一同探索和分析研究RPC服务的底层原理和实现
【Dubbo3技术专题】「云原生微服务开发实战」 一同探索和分析研究RPC服务的底层原理和实现
40 0
|
1月前
|
Dubbo Java 应用服务中间件
Spring Boot整合Dubbo+Zookeeper实现RPC调用
Spring Boot整合Dubbo+Zookeeper实现RPC调用 技术栈说明 Dubbo:Dubbo作为RPC框架,能在多个服务之间实现远程服务的调用。比如有两个独立的微服务A和B,A服务想要调用B服务时,因为两者不在同个内存空间中,不能直接调用,所以可以通过Dubbo实现这点。 功能和Spring Cloud的Feign相同,两者都是应用于微服务架构的远程调用框架 Zookeeper:作为注册中心去管理Dubbo服务,这点和Eureka、Nacos相同。 概述 通过一个示例说明Dubbo+Zookeeper在Spring Boot中的应用。 现有两个服务provider和con
116 4
|
9月前
|
Dubbo Java 应用服务中间件
Netty入门到超神系列-手撸简单版RPC框架(仿Dubbo)
原理还是比较简单 : 代理 + 线程池 + Netty 下面做一些解释: 首先需要定义一个统一的API接口,例:UserApi , 服务端(provider)需要实现这个接口,提供相应的方法UserApiImpl#save,客户端通过远程来调用该接口。 然后需要约定一个协议,服务器如何才能识别到客户端要调用哪个接口?:我这里用 “接口权限定名#方法名#参数” ,的方式来,因为是一个简单版本的RPC。服务端解析该内容就能匹配对应的接口的实现类,然后调用该方法。并把方法的返回值通过Netty写回给客户端 使用的编解码器都是比价简单的String的编解码器
115 0
|
6月前
|
负载均衡 Dubbo 网络协议
微服务RPC框架:Feign和Dubbo
微服务RPC框架:Feign和Dubbo
301 0
|
6月前
|
XML Dubbo Java
Dubbo第一讲:从RPC到Dubbo框架详解
Dubbo第一讲:从RPC到Dubbo框架详解
|
7月前
|
负载均衡 Dubbo Java
RPC框架-dubbo:架构及源码分析-初篇
在自学或面试dubbo时,相关的问题有很多,例如dubbo 的基本工作原理,这是使用过dubbo后应该知道的。包括dubbo的分层架构、长短链接选择、二进制协议支持;之后是使用方式(服务的注册、发现、调用方式),基础配置(超时时间、线程数),这些是最基本的。 在这些问题之后,就可以继续深入底层:关于连接方式,使用长连接还是短连接?为什么? dubbo的二进制协议支持哪些,之间有什么区别/优缺点等等,也可以考察在使用过程中遇到过哪些问题,是如何解决的。这些都需要深入理解,并且有真实、长时间使用经验。
147 0
|
9月前
|
XML 编解码 JSON
不满足于RPC,详解Dubbo的服务调用链路(2)
不满足于RPC,详解Dubbo的服务调用链路
181 0