认识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技术的金融摸鱼侠王有志,我们下次再见!
相关文章:
认识doubbo和rpc
开个新坑,和大家一起学习Dubbo 3.X。我们按照一个由浅入深顺序来学习,先从使用Dubbo开始,再深入Dubbo的核心原理。 今天我们就从认识Dubbo开始,整体的内容可以分为3个部分: Dubbo是什么RPC是什么Dubbo的架构 正式开…...
get_views中list的arch格式
1 日历 -> 会议 <tree string"会议" sample"1" multi_edit"1"><header><button name"action_open_composer" type"object" context"{composition_mode:mass_mail}" string"发送邮件"…...
淘宝商品销量接口API更新(总销+精准月销API)
不少客户有获取淘宝商品销量的需求,淘宝商品销量接口主要用于以下业务场景。有不齐全的欢迎大家补充。 库存管理:商家可以通过接口获取到实时的销量信息,更好地进行库存管理。供应链计划:商家可以通过接口了解到商品的销售趋势&a…...
Android 11编译第三弹 ADB开启ROOT权限
一、为什么需要adb root权限 问题:Relese版本,默认adb访问会降级到shell权限,一些敏感操作不能进行,远程调试比较麻烦。且Release版本没有su模块,不能切换Root用户。 开启adb调试以后,默认进入adb是syste…...
《TCP/IP网络编程》--基于TCP实现字符串对话和文件传输
1--基于TCP实现字符串对话 主要需求: 服务器端和客户端各传递 1 次字符串,基于 TCP 协议,传递字符串前先以 4 字节整数型方式传递字符串长度,剩余部分为字符串数据; 注:下面的代码基于 Windows 系统实现&am…...
Feign负载均衡写法
Feign主要为了面向接口编程 feign是web service客户端,是接口实现的,而ribbon是通过微服务名字访问通过RestTemplate调用的,如下: 在Feign的实现下,我们只需要创建一个接口并使用注解的方式来配置它(类似…...
OpenCV(二十八):连通域分割
目录 1.介绍连通域分割 2.像素领域介绍 3.两遍法分割连通域 4.连通域分割函数 1.介绍连通域分割 连通域分割是一种图像处理技术,用于将图像中的相邻像素组成的区域划分为不同的连通域。这些像素具有相似的特性,如相近的灰度值或颜色。连通域分割可以…...
达梦控制台还原报错“管道失败”
达梦数据库控制台还原报错“管道失败” 环境 主机操作系统:windows10 profession 达梦数据库版本:达梦7 问题背景 全新安装达梦7数据库后,创建数据库实例,需要恢复往期bat备份。在控制台配置指定搜索目录后,获取备份时…...
[杂谈]-快速了解直接内存访问 (DMA)
快速了解直接内存访问 (DMA) 文章目录 快速了解直接内存访问 (DMA)1、使用 DMA 需要什么?2、DMA介绍3、DMA 中的数据传输如何进行?4、DMA接口5、DMAC 控制器寄存器6、DMA 控制器编程模式6.1 突发模式(Burst Mode)6.2 循环窃取模式…...
java八股文面试[设计模式]——23种设计模式
设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结 在GOF编写的设计模式(可复用面向对象软件的基础)一书中说道: 本书涉及的设计模式并不描述新的或未经证实的设计,我们只收录那些在不同系统中…...
mysql(十)mysql主从复制--主库切换
概述 可能为了更迭升级服务器,或者主库出现问题,又或者只是希望重新分配容量,此时需要切换主库。 如果这是计划内的切换,会相对容易点。只需要在从库上使用CHANGE MASTER TO命令,并设置合适的值。大多数的值都是可选…...
vue3项目的src下的各个文件夹介绍
在Vue 3项目中,通常的目录结构如下所示: src/|- assets/ # 存放静态资源文件,如图片、字体等|- components/ # 存放可复用的Vue组件|- views/ # 存放页面级别的Vue组件|- router/ # 存放路由相关的配置文件|- store…...
五、编译预处理
源程序编译预处理命令一律以‘#’开头 5.1宏定义 不带参数的宏定义 # define 宏名 字符串 宏命令之后,出现宏名的地方均用其对应的字符串来替换。 宏替换是一种”机械替换“,宏定义语句后一般不加分号,因为它仅具有替换功能,…...
应用出海,Google 分享如何让数字营销素材再上层楼
数字营销广告要想取得理想的效果,广告素材是最关键的决定因素之一。 事实上米贸搜谷歌推广发现,在广告给品牌带来的销售额增量中,有 47% 都归功于广告素材。在当今自动化时代,广告素材的作用尤其重要:固然机器可以完成…...
酱香咖啡喝了没?用数据分析揭秘瑞幸咖啡的7500万用户增长策略
瑞幸 X 茅台 这波联名赢麻了,不仅狂卖 542 万杯,甚至带动茅台市值飙升200亿。 瑞幸这几年联名搞了不少,又是线条小狗的爱情故事,又是椰树、维密、周大福、足球的,下面老李就从数据分析角度,带大家来看一下…...
Grafana之魔法:揭秘数据可视化的艺术
在数据驱动的时代,如何有效地呈现和理解数据成为了每个组织和个人的核心任务。Grafana作为一个领先的开源数据可视化工具,为我们提供了强大的功能和灵活性。本文将深入探讨Grafana的魔法,以及它如何帮助我们更好地理解数据。 Grafana简介 G…...
c高级day2作业
写一个1.sh脚本,将以下内容放到脚本中: 在家目录下创建目录文件,dir 在dir下创建dir1和dir2 把当前目录下的所有文件拷贝到dir1中, 把当前目录下的所有脚本文件拷贝到dir2中 把dir2打包并压缩为dir2.tar.xz 再把dir2.tar.xz…...
第3章 【MySQL】字符集和比较规则
3.1 字符集和比较规则简介 3.1.1 字符集简介 如何存储字符串?需要建立字符与二进制数据的映射关系。建立这个关系需要: 1.把哪些字符映射成二进制数据? 2.怎么映射? 将一个字符映射成一个二进制数据的过程也叫做 编码 &#…...
2023 年全国大学生数学建模D题目-圈养湖羊的空间利用率
D题目应该是专科题目???不确定了 感觉类似一个细胞分裂问题一样,1,2,4,8, 题目1中规中矩 按照前面说的分配方法,一步一步计算进行 缺口的问题考虑反推回去,…...
攻防世界-WEB-ics-05
打开靶机 只有设备维护中心可以点开 点标签得到新的url pageindex 想到文件包含漏洞(URL中出现path、dir、file、pag、page、archive、p、eng、语言文件等相关关键字眼 利用php伪协议查看源码 出现一段base64源码,进行转码得出源码 ?pagephp://filter…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...
算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...
中医有效性探讨
文章目录 西医是如何发展到以生物化学为药理基础的现代医学?传统医学奠基期(远古 - 17 世纪)近代医学转型期(17 世纪 - 19 世纪末)现代医学成熟期(20世纪至今) 中医的源远流长和一脉相承远古至…...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...
Python实现简单音频数据压缩与解压算法
Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中,压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言,提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...
