你了解RPC么?
Posted 西瓜味儿的小志
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了你了解RPC么?相关的知识,希望对你有一定的参考价值。
先直接上定义
RPC(Remote Procedure Call):远程过程调用,它是一种进程间通信(IPC)的方式,还有另一种 IPC 方式是本地过程调用(Local Procedure Call,LPC)。
01
LPC本地过程调用
了解RPC之前,先来说说本地过程调用(啥?你都知道?我不管,我就要说 =_=):
本地过程调用通常也被称为轻量过程调用或者本地进程间通信,通过这一方式,同一计算机上的进程可以进行通信。在多任务操作系统中,它使同时运行的任务能互相会话,这些任务共享内存空间。
(读者:说的什么鬼玩意,看不懂)
别着急啊大哥,消消气、好事多磨啊,下面举个栗子理解下本地过程调用:
假设我们要调用函数 add 来计算 x + y 的结果(如下):
1 int add(int l, int r) {
2 int v = l + r;
3 return v;
4 }
5
6 int x = 10;
7 int y = 20;
8 int z = add(x, y);
执行代码第8行时,实际执行的操作为:
1、将 x 和 y 的值压栈
2、进入 add 函数,取出栈中的值10 和 20,将其赋值给 l 和 r
3、然后执行代码第2行,计算 l + r 并将结果存到 v
4、将 v 的值压栈,然后从 add 函数返回
5、在第8行代码中,从栈中取出返回的结果 30 ,并赋值给 z
上述 5 步是执行本地调用的过程。(ps:上述步骤是为了简单说明原理,实际上编译器在运算时可能会做出优化)
02
RPC远程过程调用
本地过程调用理解完了,再来看看啥是远程过程调用
远程么,意思就是要调用的函数不在本地,就上述例子而言,可以理解为 add 函数是在远程机器的某个进程中执行的。那问题来了,这咋调,还能像LPC那样了么?
哎,你还别说,那自然是不能了啊,实际上确实会带来一些新的问题:
其次,客户端在 RPC 时如何把对应的参数值传到远端?我们知道,在本地调用时只需将参数压栈,之后让函数去栈里读出来即可。但在远程调用中,客户端跟服务端进程是不同的,即无法利用内存传参。甚至另一种情况是,客户端和服务端用的不是同一种语言。因此,要解决该问题,就需要序列化和反序列化。意思就是 客户端先把参数转换成一个字节流传给服务端,服务端收到字节流后再把其转换成自己能读的格式进行读取。当然,从服务端返回给客户端的值也需要此过程。
最后,RPC 通常用在网络上,我们知道 客户端和服务端是通过网络连接的,数据的交互需要经由网络进行传输,所以 RPC 需要一个网络传输层。其作用就是将客户端的 Call ID 和序列化后的字节流传给服务端,再把序列化的运算结果返回给客户端。(相关协议是没有具体限制的,只要能完成这个传输过程的都可以)。
所以总结一下子,要实现RPC呢,就需要有三个必要的机制,大声喊出来它们是什么,对喽、它们是:
1、Call ID
2、序列化和反序列化
3、网络传输层
RPC时,客户端和服务端都做了啥?
好了,大家既然已经知道RPC是个啥了,接下来就来看看在RPC时,客户端和服务端都做了哪些事?
Client
int z = Call(ServerAddr, add, x, y)
1. 根据上面的调用从映射表中取出对应的 Call ID;
2. 将 Call ID,x ,y 进行序列化处理;
3. 将第2步得到的序列化数据包发送给ServerAddr(需要网络传输);
4. 等待 Server 将结果返回;
5. 若 Server 端调用成功,Client 将结果反序列化,再赋值给 z。
Server
1. 本地维护一个Call ID到函数指针的映射表;
2. 等待 Client 的请求;
3. 收到请求后,将收到的数据包进行反序列化,获得Call ID;
4. 通过查映射表得到 Call ID 对应的函数指针;
5. 本地调用 add 函数,得到结果;
6. 把得到的结果进行序列化,然后通过网络传输再返回给 Client。
行了,就说这些吧,大伙儿明没明白?明白了吧。
怀揣大佬梦,直面生活囧,技术不够,颜值来凑。
我是小志,一个有那么点儿梦想的咸鱼=_=。
未完待续
以上是关于你了解RPC么?的主要内容,如果未能解决你的问题,请参考以下文章