认识doubbo和rpc

开个新坑,和大家一起学习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还提供了服务治理的能力。

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服务的设计参考:

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的官方文档使用了新的抽象架构:

将Dubbo从整体划分了两层:

  • Dubbo数据面:提供RPC功能的核心部分,通过RPC协议进行通信,定义了调用规范,完成了数据交互的编码和解码功能做;
  • 服务治理控制面:服务治理的抽象,包含了注册中心,流量管控策略,Dubbo Admin控制台等。

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

图例说明

  • 图中左边淡蓝背景的为服务消费方使用的接口,右边淡绿色背景的为服务提供方使用的接口,位于中轴线上的为双方都用到的接口;
  • 图中从下至上分为十层,各层均为单向依赖,右边的黑色箭头代表层之间的依赖关系,每一层都可以剥离上层被复用,其中,Service和Config层为API,其它各层均为SPI
  • 图中绿色小块的为扩展接口,蓝色小块为实现类,图中只显示用于关联各层的实现类;
  • 图中蓝色虚线为初始化过程,即启动时组装链,红色实线为方法调用过程,即运行时调时链,紫色三角箭头为继承,可以把子类看作父类的同一个节点,线上的文字为调用的方法。

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

各层说明

  • config配置层:对外配置接口,以ServiceConfig,ReferenceConfig为中心,可以直接初始化配置类,也可以通过Spring解析配置生成配置类
  • proxy服务代理层:服务接口透明代理,生成服务的客户端Stub和服务器端Skeleton,以ServiceProxy为中心,扩展接口为ProxyFactory
  • registry注册中心层:封装服务地址的注册与发现,以服务URL为中心,扩展接口为RegistryFactory,Registry,RegistryService
  • cluster路由层:封装多个提供者的路由及负载均衡,并桥接注册中心,以Invoker为中心,扩展接口为Cluster,Directory,Router,LoadBalance
  • monitor监控层:RPC调用次数和调用时间监控,以Statistics为中心,扩展接口为MonitorFactory,Monitor,MonitorService
  • protocol远程调用层:封装RPC调用,以Invocation,Result为中心,扩展接口为Protocol,Invoker,Exporter
  • exchange信息交换层:封装请求响应模式,同步转异步,以Request,Response为中心,扩展接口为Exchanger,ExchangeChannel,ExchangeClient,ExchangeServer
  • transport网络传输层:抽象Mina和Netty为统一接口,以Message为中心,扩展接口为Channel,Transporter,Client,Server,Codec
  • serialize数据序列化层:可复用的一些工具,扩展接口为Serialization,ObjectInput,ObjectOutput,ThreadPool

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

支持协议

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

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

不要看到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服务,需要考虑如何将服务保存到存根中?使用哪种方式进行交互?交互的数据结构该如何设计?


如果本文对你有帮助的话,还请多多点赞支持。如果文章中出现任何错误,还请批评指正。最后欢迎大家关注分享硬核Java技术的金融摸鱼侠 王有志,我们下次再见!

相关推荐
现在,此刻13 分钟前
leetcode 11. 盛最多水的容器 -java
java·算法·leetcode
DKPT41 分钟前
Java设计模式之开闭原则介绍与说明
java·设计模式·开闭原则
hyy27952276841 小时前
企业级WEB应用服务器TOMCAT
java·前端·tomcat
布朗克1681 小时前
Spring Boot项目通过Feign调用三方接口的详细教程
java·spring boot·feign
Arva .1 小时前
Spring基于XML的自动装配
xml·java·spring
帅得不敢出门3 小时前
Android Framework定制长按电源键关机的窗口
android·java·framework
fatfishccc3 小时前
循序渐进学 Spring (上):从 IoC/DI 核心原理到 XML 配置实战
xml·java·数据库·spring·intellij-idea·ioc·di
小厂永远得不到的男人4 小时前
一篇文章搞懂 java 反射
java·后端
勇往直前plus4 小时前
一文学习nacos和openFeign
java·学习·微服务·openfeign
Warren984 小时前
公司项目用户密码加密方案推荐(兼顾安全、可靠与通用性)
java·开发语言·前端·javascript·vue.js·python·安全