首页 > 其他分享 >RPC(远程过程调用)详解

RPC(远程过程调用)详解

时间:2024-04-27 14:22:19浏览次数:28  
标签:调用 RPC 详解 序列化 ID 服务端 客户端

一、RPC是什么

RPC是指远程过程调用,也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。

二、RPC需要解决的问题

1、Call ID映射

我们怎么告诉远程机器我们要调用funA,而不是funB或者funC呢?在本地调用中,函数体是直接通过函数指针来指定的,我们调用funA,编译器就自动帮我们调用它相应的函数指针。但是在远程调用中,函数指针是不行的,因为两个进程的地址空间是完全不一样的。

所以,在RPC中,所有的函数都必须有自己的一个ID。这个ID在所有进程中都是唯一确定的。客户端在做远程过程调用时,必须附上这个ID。然后我们还需要在客户端和服务端分别维护一个 {函数 <–> Call ID} 的对应表。两者的表不一定需要完全相同,但相同的函数对应的Call ID必须相同。

【Note】当客户端需要进行远程调用时,它就查一下这个表,找出相应的Call ID,然后把它传给服务端,服务端也通过查表,来确定客户端需要调用的函数,然后执行相应函数的代码。

 

2、序列化和反序列化

客户端怎么把参数值传给远程的函数呢?在本地调用中,我们只需要把参数压到栈里,然后让函数自己去栈里读就行。

但是在远程过程调用时,客户端跟服务端是不同的进程,不能通过内存来传递参数。甚至有时候客户端和服务端使用的都不是同一种语言(比如服务端用C++,客户端用Java或者Python)。

【Note】这时候就需要客户端把参数先转成一个字节流(编码),传给服务端后,再把字节流转成自己能读取的格式(解码)。这个过程叫序列化和反序列化。同理,从服务端返回的值也需要序列化反序列化的过程。

3、网络传输

远程调用往往用在网络上,客户端和服务端是通过网络连接的。所有的数据都需要通过网络传输,因此就需要有一个网络传输层。

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

所以,要实现一个RPC框架,其实只需要把以上三点实现了就基本完成了。Call ID映射可以直接使用函数字符串,也可以使用整数ID。映射表一般就是一个哈希表。序列化反序列化可以自己写,也可以使用Protobuf或者FlatBuffers之类的。网络传输库可以自己写socket,或者用asio,ZeroMQ,Netty之类。

4、RPC的调用流程图

 

三、常用的RPC框架

  • gRPC是Google公布的开源软件,基于最新的HTTP2.0协议,并支持常见的众多编程语言。我们知道HTTP2.0是基于二进制的HTTP协议升级版本,目前各大浏览器都在快马加鞭的加以支持。这个RPC框架是基于HTTP协议实现的,底层使用到了Netty框架的支持。
  • Thrift是Facebook的一个开源项目,主要是一个跨语言的服务开发框架。它有一个代码生成器来对它所定义的IDL定义文件自动生成服务代码框架。用户只要在其之前进行二次开发就行,对于底层的RPC通讯等都是透明的。不过这个对于用户来说的话需要学习特定领域语言这个特性,还是有一定成本的。
  • Dubbo是阿里集团开源的一个极为出名的RPC框架,在很多互联网公司和企业应用中广泛使用。协议和序列化框架都可以插拔是及其鲜明的特色。同样的远程接口是基于Java Interface,并且依托于spring框架方便开发。可以方便的打包成单一文件,独立进程运行,和现在的微服务概念一致。

标签:调用,RPC,详解,序列化,ID,服务端,客户端
From: https://www.cnblogs.com/lgx5/p/18161999

相关文章

  • 微服务想缓存一些数据,不希望重复调用。java SoftReference软引用存储缓存
    背景:微服务我们要调用字典数据,但是很多都是要重复调用的,没有缓存,我为了设置一个应用的缓存,并且可以定时清理,更新 首先定义两个静态数据,。一个软连接缓存,一个定时清理线程privatestaticSoftReference<Map<String,Map<String,DictionaryVo>>>plmDicMapCache=newSoftR......
  • RabbitMQ工作原理详解
    RabbitMQ的工作原理主要涉及生产者、消费者、交换机、队列和绑定等组件的交互。以下是其工作原理的详细解释:1、生产者(Producer):生产者负责创建消息并将其发送到RabbitMQ服务器。这些消息可以包含任何类型的数据,如JSON、XML等。生产者首先与RabbitMQ服务器建立连接,并创建一个通......
  • SQL窗口分析函数使用详解系列三之偏移量类窗口函数
    1.综述本文以HiveSQL语法进行代码演示。对于其他数据库来说同样也适用,比如SparkSQL,FlinkSQL以及Mysql8,Oracle,SqlServer等传统的关系型数据库。已更新第一类聚合函数类,点击这里阅读①SQL窗口函数系列一之聚合函数类②SQL窗口函数系列二之分组排序窗口函数本节介绍Hive窗口分......
  • C#同步方法中如何调用异步方法
    最近看了个关于同步方法中调用异步方法的文章,有感而发,先把代码放在这里,有时间再补充理解namespace同步方法中调用异步方法{internalclassProgram{//staticvoidMain(string[]args)//{//Console.WriteLine("start"+DateTim......
  • Linux 系统故障排查,一文详解
    导读有时候会遇到一些疑难杂症,并且监控插件并不能一眼立马发现问题的根源。这时候就需要登录服务器进一步深入分析问题的根源。那么分析问题需要有一定的技术经验积累,并且有些问题涉及到的领域非常广,才能定位到问题。所以,分析问题和踩坑是非常锻炼一个人的成长和提升自我能力。如......
  • MySQL 5.7升级8.0过程(详解)
    记一次MySQL5.7升级8.0的详细过程,聊聊我的思路,希望可以帮助大家。以一个例子为切入点一、升级背景为什么要升级到MySQL8.0?大概多久进行一次?大家可以参考下图记录的各个版本的发布时间,来确认各个版本的最终补丁日期:  从上图来看,当前处在官方支持生命周期的版本是MySQL......
  • qt封装dll并静态调用其它接口
    开发套件为QT5.9+MinGW编译器首先创建dll,第一步创建一个打开pro文件,因为我们创建的是app,需要的是dll,修改app->lib,注意不是dll其次,静态调用自己的底层库在工程中加入头文件,在pro添加dll的路径(注意这里静态调用没有用到lib文件)添加示例接口将编译的dll放入测试环境......
  • Js链式调用面试题
    Js链式调用需求:要求可以链式调用对象的方法,该对象有四个方法,加减乘除,一个get结果方法eg:counter.add(3).sub(1).get()//2方法一通过Es6实现classCounter{privateresult=0;add(val:number){this.result+=val;returnthis;}sub(val:nu......
  • 什么是 Docker?Docker详解,7分钟学会
    Docker容器是一种打包格式,可通过标准格式打包应用的所有代码和依赖关系,确保应用能够快速、可靠地在计算环境下运行。Docker容器是一种广受欢迎的轻量级、可执行的独立容器,其中包含应用运行所需的一切要素,包括库、系统工具、代码和运行时。此外,Docker还是一个软件平台,支持开发人......
  • HarmonyOS 应用生命周期有哪些? 按返回键会调用哪些生命周期?
    UIAbility生命周期:onCreate:页面初始化,变量定义,资源加载。onWindowStageCreate:设置UI界面加载、设置WindowStage的事件订阅。onForeground:切换至前台,申请系统需要的资源,或者重新申请在onBackground()中释放的资源。onBackground:切换至后台,释放UI界面不可见时无用的资......