当前位置: 首页 > news >正文

【gRPC】什么是RPC——介绍一下RPC

       说起RPC,博主使用CPP手搓了一个RPC项目,RPC简单来说,就是远程过程调用:我们一般在本地传入数据进行执行函数,然后返回一个结果;当我们使用RPC之后,我们可以将函数的执行过程放到另外一个服务器上,而不是在本地创建一个函数栈帧,将函数执行所需要的一些东西压入到栈中。下面,我们来学习RPC!!!

一、远程过程调用带来的问题

       在远程调用时,我们需要执行的函数体是在远程的机器上,也就是说,add是在另一个进程中执行的。这就带来了几个问题:

1.1 Caller ID 映射

       我们怎么告诉远程机器我们要调用add,而不是sub或者 Foo呢??在本地调用中,直接通过函数指针来指定的,我们调用add,编译器就自动帮我们调用它相应的函数指针。但是在远程调用中,指针是不行的,因为两个进程的地址空间是完全不一样的。所以,在RPC中,所有的函数都必须有自己的一个ID。

       这个ID在所有进程中都是唯一确定的。客户端在做远程调用时,必须附上这个ID。然后我们还需要在客户端和服务端中分别维护一个 【函数 <----> Call ID】的对应表。两者的表不一定需要完全相同,但是相同的函数对应的 Call ID 必须相同。当客户端需要进行远程调用时,他就查一下这个表,找出相应的 Call ID ,然后将他传入到服务端,服务端也通过查表来确定客户端需要调用的函数,然后执行相应函数的代码。

1.2 序列化和反序列化

       客户端怎么把参数值传给远程的函数呢??在本地调用中,我们只需要把参数压入到栈中,然后让函数自己去栈萝莉读就行。但是在远程过程调用时,客户端根服务端是不同的进程,不能通过内存来传递参数。甚至有时候客户端和服务端使用的都不是同一种语言(比如服务端用C++,客户端使用 Java 或者 python)。这时候就需要客户端把参数先转成一个字节流,传给服务端后,再把字节流转成自己能读取的格式。这个过程叫做序列化和反序列化。同理,从服务端返回的值夜需要通过序列化和反序列化的过程。

1.3 网络传输

       远程调用往往用在网络中,客户端和服务端是通过网络连接的。所有的数据都需要通过网络传输,因此就需要有一个网络传输层。网络传输层需要把 Call ID 和序列化后的参数字节流传给服务端,然后再把序列化后的调用结果传回给客户端。只要能完成这两者的,都可以用作为传输层使用。因此,他所使用的协议其实是不限的,只要可以完成传输就行了。尽管大部分RPC框架都使用TCP协议,但是其实UDP也是可以的,而gRPC干脆就使用HTTP2。

二、上述三个机制的解决方法

当我们解决了上述的三个问题,就可以实现RPC了,具体过程如下:

2.1 client 端可以解决的问题

  • 将这个调用映射为 Call ID ,这里假设使用最简单的字符串当 Call ID 的方法
  • 将 Call ID ,a 和 b序列化。可以直接将他们的值以二进制形式打包
  • 将2中得到的数据包发送给 ServerAddr,这就需要使用网络传输层
  • 等待服务器调用成功,那么就将结果反序列化,并赋值给total

2.2 server 端可以解决的问题

  • 在本地维护一个 Call ID 到函数指针的映射 call_id_map,我们可以使用dict来完成
  • 等待请求,包括多线程的并发处理能力
  • 得到一个请求后,将其数据包反序列化,得到相应的函数指针
  • 将 a 和 rb 反序列化后,在本地调用 add 函数,得到结果
  • 将结果序列化后通过网络返回给 Client

在上面的整个流程中,其中:

  • Call ID 映射可以直接使用函数字符串,也可以使用整数ID。映射表一般就是一个哈希表
  • 序列化和反序列化可以自己写,也可以使用 protobuf 或者 FlatBuffers 之类的
  • 网络传输库可以自己写 socket ,或者使用 asio,ZeroMQ、Netty 之类的

       实际上真正的开发过程中,除了上面的基本功能之外,还需要更多的细节:网络错误,流量控制,超时和重传。

三、最后,如何将远程的这些过程写出本地函数调用的感觉??

下面,我们可以使用 go 语言来进行实现这个问题,因为在 go 语言中提供的包还是很全的。

我们分为服务端和客户端来进行编写代码:我们先来看一看服务端的代码:

package mainimport ("encoding/json""fmt""net/http""strconv"
)func main() {// http// 返回的格式化为:json{ "data"=3 }// 1. callID 的问题 r.URL.Path  2. 数据的传输协议 url 的参数传递协议  3. 网络传输协议 httphttp.HandleFunc("/add", func(w http.ResponseWriter, r *http.Request) {_ = r.ParseForm() // 解析参数fmt.Println("Path: ", r.URL.Path)a, _ := strconv.Atoi(r.Form["a"][0])b, _ := strconv.Atoi(r.Form["b"][0])w.Header().Set("Content-Type", "application/json; charset=utf-8")jData, _ := json.Marshal(map[string]interface{}{"data": a + b,})_, _ = w.Write(jData)})_ = http.ListenAndServe(":8080", nil)
}

客户端中的代码如下:

package mainimport ("encoding/json""fmt""github.com/kirinlabs/HttpRequest"
)type ResponseData struct {Data int `json:"data"`
}func add(a, b int) int {// 传输协议req := HttpRequest.NewRequest() // 创建一个requestres, _ := req.Get(fmt.Sprintf("http://127.0.0.1:8080/%s?a=%d&b=%d", "add", a, b))body, _ := res.Body()rspData := ResponseData{}_ = json.Unmarshal(body, &rspData)return rspData.Data
}func main() {// 实现 rpcadd(1, 2)
}

四、RPC开发的要素分析

4.1 RPC开发的四大要素

       RPC技术在架构设计上有四个部分组成,分别是:客户端,客户端存根,服务端。服务端存根。下面,我们来一一介绍:

  • 客户端:服务调用发起方,也称为服务消费者
  • 客户端存根:该程序运行在客户端所在的计算机机器上,主要用来存储要调用的服务器的地址,另外,该程序还负责将客户端请求远端服务器程序的数据信息打包成数据包,通过网络发送给服务端Stub程序,其次,还要接受服务器Stub程序发送的调用结果数据包,并解析返回给客户端。
  • 服务端:远端的计算机机器上运行的程序,其中有客户端要调用的方法
  • 服务端存根:接收客户Stub程序通过网络发送的请求消息数据包,并调用服务端中真正的程序功能方法,完成功能调用,其次,将服务端执行调用的结果进行数据处理打包发送给客户端Stub程序。

       了解完了RPC技术的组成结构,我们来看一下具体是如何实现客户端到服务端的调用的。实际上,如果我们想要在网络中的任意两台计算机上实现进程调用进程,需要解决很多问题,比如:

  • 两台物理机器在网络中要建立稳定可靠的通信连接
  • 两台服务器的通信协议的定义问题,即两台服务器上的程序如何识别对方的请求和返回结果。也就是说两台计算机必须能够识别对方发来的信息,并且能够识别出其中的请求含义和返回含义,然后才能进行处理,这其实就是通信协议要完成的工作。

在上图中,通过10步完成了RPC,下面我们来具体描述一下RPC每一步的调用过程:

  1. 客户端想要发起一个远程过程调用,首先要通过调用本地客户端Stub程序的方式调用想要使用的功能方法名;
  2. 客户端Stub程序接收到了客户端的功能调用请求,将客户端请求调用的方法名,携带的参数等信息做序列化,操作,并打包成数据包;
  3. 客户端Stub查找到远程服务器程序的IP地址,调用Socket通信协议,通过网络发送给服务端
  4. 服务端Stub程序接收到客户端发送的数据包信息,并通过约定好的协议将数据进行反序列化,得到请求的方法名和请求参数等信息
  5. 服务端Stub程序准备相关数据,调用本地的Server对应的功能方法进行,并存入相应的参数,进行业务处理
  6. 服务端程序根据已有的业务逻辑执行调用过程,等到业务执行结束之后,将执行结果返回给服务端Stub程序
  7. 服务端Stub程序将程序调用结果按照约定的协议进行序列化,并通过网络发送回给客户端Stub程序
  8. 客户端Stub接收到服务端Server发送返回的数据,对数据进行反序列化的操作,并将调用返回的数据传递给客户端请求发送者
  9. 客户端请求发起者得到调用结果,整个RPC调用过程结束

五、RPC需要使用到的术语

       通过上文一系列的文字描述和讲解,我们已经了解了RPC的由来和整个RPC调用过程。我们可以看到RPC是一系列操作的集合,其中涉及了很多对于数据的操作,以及网络通信。因此,我们对RPC中涉及到的技术做一个总结和分析:

  • 动态代理技术:上文中我们提到的Client Stub 和Server Stub 程序,在具体的编码和开发实践的过程中,都是使用动态代理技术自动生成的一段程序
  • 序列化和反序列化:在RPC调用的过程中,我们可以看到数据需要在一台机器上传输到另一台机器上。在互联网中,所有的数据都是以字节的形式进行传输的。而我们在编程的过程中,往往都需要使用数据对象,因此想要在网络上将对象和相关变量进行传输,就需要对数据对象做序列化和反序列化的操作。

相关文章:

【gRPC】什么是RPC——介绍一下RPC

说起RPC&#xff0c;博主使用CPP手搓了一个RPC项目&#xff0c;RPC简单来说&#xff0c;就是远程过程调用&#xff1a;我们一般在本地传入数据进行执行函数&#xff0c;然后返回一个结果&#xff1b;当我们使用RPC之后&#xff0c;我们可以将函数的执行过程放到另外一个服务器上…...

谈谈你对AQS的理解

AQS 是多线程同步器&#xff0c;它是 JUC 包中多个组件的底层实现&#xff0c;如 Lock、CountDownLatch、Semaphore等都用到了AQS。 从本质上来说&#xff0c;AQS 提供了两种锁机制&#xff0c;分别是排它锁&#xff0c;和共享锁。 排它锁&#xff0c;就是存在多线程竞争同一…...

Bitcoin全节点搭建

1. wget https://bitcoincore.org/bin/bitcoin-core-0.20.1/bitcoin-0.20.1-x86_64-linux-gnu.tar.gz 2.tar -xzvf bitcoin-0.20.1-x86_64-linux-gnu.tar.gz mv bitcoin-0.20.1 bitcoin 3.创建配置文件&#xff08;bitcoin.conf&#xff09; mkdir -p /btc_data mkdir ~/.b…...

【mysql进阶】4-6. InnoDB 磁盘文件

InnoDB 磁盘⽂件 1 InnoDB存储引擎包含哪些磁盘⽂件&#xff1f; &#x1f50d; 分析过程 ✅ 解答问题 InnoDB的磁盘⽂件主要是表空间⽂件和其他⽂件&#xff0c;表空间包括&#xff1a;系统表空间、独⽴表空间、通⽤表空间、临时表空间和撤销表空间&#xff1b;其他⽂件有重做…...

HexForge:一款用于扩展安全汇编和十六进制视图的IDA插件

关于HexForge HexForge是一款用于扩展安全汇编和十六进制视图的IDA插件&#xff0c;在该工具的帮助下&#xff0c;广大研究人员可以方便地直接从 IDA Pro 界面数据解码、解密或执行安全数据审计任务。 功能介绍 1、从 IDA 的反汇编或十六进制视图复制原始十六进制&#xff1b;…...

WORFBENCH:一个创新的评估基准,目的是全面测试大型语言模型在生成复杂工作流 方面的性能。

2024-10-10,由浙江大学和阿里巴巴集团联合创建的WORFBENCH&#xff0c;一个用于评估大型语言模型&#xff08;LLMs&#xff09;生成工作流能力的基准测试。它包含了一系列的测试和评估协议&#xff0c;用于量化和分析LLMs在处理复杂任务时分解问题和规划执行步骤的能力。WORFBE…...

SpringBoot 集成 Activiti 7 工作流引擎

一. 版本信息 IntelliJ IDEA 2023.3.6JDK 17Activiti 7 二. IDEA依赖插件安装 安装BPM流程图插件&#xff0c;如果IDEA的版本超过2020,则不支持actiBPM插件。我的IDEA是2023版本我装的是 Activiti BPMN visualizer 插件。 在Plugins 搜索 Activiti BPMN visualizer 安装创建…...

UVM初学篇 -(22)UVM field_automation 域的自动化机制

field_automation机制是域的自动化的机制&#xff0c;这个机制的最大的优点是可以对一些变量进行批量的处理&#xff0c;比如对象拷贝、克隆、打印之类的变量。 一、 成员变量的注册 使用field_automation机制首先要用uvm_field 系列宏完成变量的注册&#xff0c;类中的成员变…...

STL二分查找

本课主要介绍容器部分里面的二分查找函数。涉及的函数有 3 个&#xff0c;这 3 个函数的强两个输入参数都和迭代器有关&#xff0c;或者说参数是可以迭代的&#xff0c;而第三个参数则是你要查找的值。 1. binary_search binary_search 的返回结果是 bool 值&#xff0c;如果找…...

啤酒游戏—企业经营决策沙盘

感谢黄浦区文华学院的邀请&#xff0c;今年是为南房集团开展系统思考培训的第二年。我们现在为客户设计的一整年系统思考训练中&#xff0c;会将系统环路结构图与真实议题研讨作为前置内容&#xff0c;让大家在理解整体框架后&#xff0c;再体验麻省理工学院系统动力学著名的“…...

尚硅谷-react教程-求和案例-@redux-devtools/extension 开发者工具使用-笔记

## 7.求和案例_react-redux开发者工具的使用(1).npm install redux-devtools/extension(2).store中进行配置import { composeWithDevTools } from redux-devtools/extension;export default createStore(allReducer,composeWithDevTools(applyMiddleware(thunk))) src/redux/s…...

【动手学强化学习】part2-动态规划算法

阐述、总结【动手学强化学习】章节内容的学习情况&#xff0c;复现并理解代码。 文章目录 一、什么是动态规划&#xff1f;1.1概念1.2适用条件 二、算法示例2.1问题建模2.2策略迭代&#xff08;policyiteration&#xff09;算法2.2.1伪代码2.2.2完整代码2.2.3运行结果2.2.4代码…...

【python爬虫实战】爬取全年天气数据并做数据可视化分析!附源码

由于篇幅限制&#xff0c;无法展示完整代码&#xff0c;需要的朋友可在下方获取&#xff01;100%免费。 一、主题式网络爬虫设计方案 1. 主题式网络爬虫名称&#xff1a;天气预报爬取数据与可视化数据 2. 主题式网络爬虫爬取的内容与数据特征分析&#xff1a; - 爬取内容&am…...

初识Linux · 动静态库(incomplete)

目录 前言&#xff1a; 静态库 动态库 前言&#xff1a; 继上文&#xff0c;我们从磁盘的理解&#xff0c;到了文件系统框架的基本搭建&#xff0c;再到软硬链接部分&#xff0c;我们开始逐渐理解了为什么运行程序需要./a.out了&#xff0c;这个前面的.是什么我们也知道了。…...

华为OD机试 - 匿名信(Java 2024 E卷 100分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;E卷D卷A卷B卷C卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加…...

通过rancher2.7管理k8s1.24及1.24以上版本的k8s集群

目录 初始化实验环境 安装Rancher 登录Rancher平台 通过Rancher2.7管理已存在的k8s最新版集群 文档中的YAML文件配置直接复制粘贴可能存在格式错误&#xff0c;故实验中所需要的YAML文件以及本地包均打包至网盘. 链接&#xff1a;https://pan.baidu.com/s/1oYX4eGoBtW_R-7i…...

text-align的属性justify

text-align常用的属性是left、center、right&#xff0c;具体的可参考css解释&#xff0c;今天重点记录的对象是justify justify 可以使文本的两端都对齐在两端对齐文本中&#xff0c;文本行的左右两端都放在父元素的内边界上。然后&#xff0c;调整单词和字母间的间隔&#x…...

使用python自制桌面宠物,好玩!——枫原万叶桌宠,可以直接打包成exe去跟朋友炫耀。。。

大家好&#xff0c;我是小黄。 今天我们使用python实现一个桌面宠物。只需要gif动态图片就行。超级简单容易上手。 #完整源代码可在下方图片免费获取 一&#xff1a;下载相关的库文件。 我们本次使用到的库文件为&#xff1a;tkinter和pyautogui 下载命令&#xff1a; pip…...

使用 ASP.NET Core 8.0 创建最小 API

构建最小 API&#xff0c;以创建具有最小依赖项的 HTTP API。 它们非常适合需要在 ASP.NET Core 中仅包括最少文件、功能和依赖项的微服务和应用。 本教程介绍使用 ASP.NET Core 生成最小 API 的基础知识。 在 ASP.NET Core 中创建 API 的另一种方法是使用控制器。 有关在最小 …...

气候服务平台ClimateSERV2.0简介(python)

1 简介 ClimateSERV 2.0允许开发从业者、科学家/研究人员和政府决策者可视化和下载历史降雨数据、植被状况数据以及 180 天的降雨和温度预报&#xff0c;以增进对农业和水资源供应相关问题的理解并做出改进的决策。 这些数据可以通过 Web 应用程序直接访问&#xff0c;也可以…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap&#xff08;位图&#xff09;是Android应用内存占用的“头号杀手”。一张1080P&#xff08;1920x1080&#xff09;的图片以ARGB_8888格式加载时&#xff0c;内存占用高达8MB&#xff08;192010804字节&#xff09;。据统计&#xff0c;超过60%的应用OOM崩溃与Bitm…...

Fabric V2.5 通用溯源系统——增加图片上传与下载功能

fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...