什么是RPC?

本文介绍了RPC(Remote Procedure Call)远程过程调用,它是用于网络中不同计算机程序通信的协议,常用于分布式系统。阐述了其工作原理,介绍了同步、异步、双向流三种常见类型,还分析了远程调用带来的Call ID映射、序列化和反序列化、网络传输等问题及解决办法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、RPC简介

RPC(Remote Procedure Call)远程过程调用是一种协议,用于在网络中不同计算机上运行的程序之间进行通信。它允许一个程序像调用本地服务一样调用另一个计算机上的服务,而无需了解底层网络细节。RPC通常用于分布式系统中,使得不同机器上的程序能够无缝协作。

二、RPC工作原理

RPC的工作原理是将调用方的函数调用封装成网络请求,并发送到远程计算机上的服务端。服务端接收到请求后,解包并执行对应的函数,然后将结果返回给调用方。整个过程对调用方来说是透明的,就像是在本地调用函数一样。

三、RPC类型

RPC有多种实现方式,常见的包括:

同步RPC:客户端发起调用后,会阻塞等待服务端返回结果。这种方式简单直接,但可能导致客户端长时间无响应。

异步RPC:客户端发起调用后,不会立即等待结果,而是继续执行其他任务。当服务端返回结果时,会通过某种机制通知客户端。这种方式可以提高系统的并发性能。

双向流RPC:客户端和服务端可以同时发送和接收数据流,实现更复杂的交互模式。

四、远程过程调⽤带来的新问题

在远程调⽤时,我们需要执⾏的函数体是在远程的机器上的,也就是说,add 是在另⼀个进程中执⾏的。这就带
来了⼏个新问题:

1. Call ID 映射。
我们怎么告诉远程机器我们要调⽤ add,⽽不是 sub 或者Foo 呢?在本地调⽤中,函数体是直接通过函数指针来指定的,我们调⽤add,编译器就⾃动帮我们调⽤它相应的函数指针。但是在远程调⽤中,函数指针是不⾏的,因为两个进程的地址空间是完全不⼀样的。所以,在RPC 中,所有的函数都必须有⾃⼰的⼀个 ID。这个 ID 在所有进程中都是唯⼀确定的。客户端在做远程过程调⽤时,必须附上这个ID。然后我们还需要在客户端和服务端分别维护⼀个 {函数 <–> Call ID}的对应表。两者的表不⼀定需要完全相同,但相同的函数对应Call ID 必须相同。当客户端需要进⾏远程调⽤时,它就查⼀下这个表,找出相应的Call ID,然后把它传给服务端,服务端也通过查表,来确定客户端需要调⽤的函数,然后执⾏相应函数的代码。
2. 序列化和反序列化。
客户端怎么把参数值传给远程的函数呢?在本地调⽤中,我们只需要把参数压到栈⾥, 然后让函数⾃⼰去栈⾥读就⾏。但是在远程过程调⽤时,客户端跟服务端是不同的进程,不能通过内存来传递参数。甚⾄有时候客户端和服务端使⽤的都不是同⼀种语⾔(⽐如服务端⽤ C++,客户端⽤ Java 或者 Python)。这时候就需要客户端把参数先转成⼀个字节流,传给服务端后,再把字节流转成⾃⼰能读取的格式。这个过程叫序列化和反序列化。同理,从服务端返回的值也需要序列化反序列化的过程。
3. ⽹络传输。
远程调⽤往往⽤在⽹络上,客户端和服务端是通过⽹络连接的。所有的数据都需要通过⽹络传 输,因此就需要有⼀个⽹络传输层。⽹络传输层需要把 Call ID 和序列化后的参数字节流传给服务端,然后再把序列化后的调⽤结果传回客户端。只要能完成这两者的,都可以作为传输层使⽤。因此,它所使⽤的协议 其实是不限的,能完成传输就⾏。尽管⼤部分RPC 框架都使⽤ TCP 协议,但其实 UDP 也可以,⽽ gRPC ⼲ 脆就⽤了 HTTP2。Java 的 Netty也属于这层的东⻄。

解决了上⾯三个机制,就能实现 RPC 了,具体过程如下:

client 端解决的问题:

1. 将这个调⽤映射为Call ID。这⾥假设⽤最简单的字符串当Call ID的⽅法
2. 将Call ID,a和b序列化。可以直接将它们的值以⼆进制形式打包
3. 把2中得到的数据包发送给ServerAddr,这需要使⽤⽹络传输层
4. 等待服务器返回结果
4. 如果服务器调⽤成功,那么就将结果反序列化,并赋给total

server 端解决的问题

1. 在本地维护⼀个Call ID到函数指针的映射call_id_map,可以⽤dict完成
2. 等待请求,包括多线程的并发处理能⼒
3. 得到⼀个请求后,将其数据包反序列化,得到Call ID
4. 通过在call_id_map中查找,得到相应的函数指针
5. 将a和rb反序列化后,在本地调⽤add函数,得到结果
6. 将结果序列化后通过⽹络返回给Client

在上⾯的整个流程中,估计有部分同学看到了熟悉的计算机⽹络的流程和 web 服务器的定义。
所以要实现⼀个 RPC 框架,其实只需要按以上流程实现就基本完成了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值