一分钟了解什么是RPC

前言

    在介绍RPC之前,先介绍另外一个概念:进程间通信(IPC,Inter-Process Communication)

  • IPC:是指至少两个进程或线程间传送数据或信号的一些技术或方法。

    我们知道进程是计算机系统分配资源的最小单位。每个进程都有自己独立的系统资源,彼此相互隔离。为了使不同的进程之间能够互相访问资源并进行协调工作,于是就有了进程间通信(IPC)。

  • 进程间通信技术包括:消息传递、同步、共享内存和远程过程调用。

    由于进程可以运行在同一台机器上也可以运行在通过网络连接的不同机器上,于是IPC可分为两种类型:

  • 本地过程调用(LPC):顾名思义,就是运行在同一台机器上进程间通信。多用在多任务操作系统中,是的同时运行的的任务之间能够相互会话。这些任务共享内存空间使任务同步和互发消息
  • 远程过程调用(RPC):RPC类似于LPC,其目的是使通过网络连接的不同机器进程间能够互发消息

 

什么是RPC

    RPC的全称是Remote Procedure Call(远程过程调用),是一种基于TCP/IP协议的进程间的通信方式。该机制运行调用另一个地址空间(通常是共享网络的另一台机器)的过程或函数,而不是程序员显式编码这个远程调用的细节,也就是说程序员无论是调用本地还是远程,本质上编写的调用代码基本相同。简单的说:

  • RPC就是从一台机器(客户端)上通过参数传递的方式调用另一台机器(服务器)上的一个函数或方法(可以统称为服务)并得到返回的结果。
  • RPC 会隐藏底层的通讯细节(不需要直接处理Socket通讯或Http通讯) RPC 是一个请求响应模型。
  • 客户端发起请求,服务器返回响应(类似于Http的工作方式) RPC 在使用形式上像调用本地函数(或方法)一样去调用远程的函数(或方法)

    RPC的主要功能目标是让构建分布式计算(应用)更容易,在提供强大的远程调用能力时不损失本地调用的语义间性。

 

举例

    比如有两台服务器A和B,一个应用部署在服务器A上,一个部署在B上,A想要调用B服务器上的应用提供的函数或方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传递调用的数据,这就需要用到RPC了。这个过程就需要解决一些问题:

  • 第一:要解决通讯问题。主要是通过在客户端和服务器之间建立TCP连接,远程过程调用的所有要交换的数据都通过这个连接传输。连接可以是短连接(调用完就断掉),也可以是长连接(多个远程调用共享一个连接)
  • 第二:要解决寻址的问题。也就是A服务器上的应用怎么告诉底层的RPC框架,如何连接到B服务器(入主机或IP地址)以及特定的端口,调用的方法名是什么,这样才能成功调用。比如基于Web服务协议栈的RPC,就哟啊提供一个EndPoint URI,或者是从UDDI服务上查找。如果是RMI调用的话,还需要一个RMI Registry来注册服务的地址。
  • 第三:当A服务器上的应用发起远程过程调用时,方法的参数需要通过底层的网络协议如TCP传递到B服务器,由于网络协议是基于二进制的,内存中的参数值需要序列化成二进制形式,即序列化(Serialize)和编组(marshal),通过寻址和传输将序列化的二进制发送到B服务器。
  • 第四:B服务器收到调用请求后,需要对参数进行反序列化,恢复为内存中的表达方式,然后找到对应的方法(寻址的一部分)进行本地调用,然后得到返回值。
  • 第五:返回值还要发送回服务器A上应用,也要经过序列化的方式进行。服务器A接到返回值后,经过反序列化恢复为内存中的表达形式,供A服务器上的应用使用。

一分钟了解什么是RPC_第1张图片

 

RPC实现原理

通过上面的五个要解决的问题,可以将其总结起来归为三个问题,只要实现了这个三个机制,就能实现RPC

  • 第一:Call ID映射。即解决寻址问题,告诉远程服务器B我要调用函数a,而不是函数b。在本地调用中,函数体是直接通过函数指针来指定的,我们调用函数a,编译器就自动帮我们调用它相应的函数指针。但是在远程调用中,函数指针肯定不行,因为两个进程的地址空间完全不一样。所以,在RPC中,所有的函数都必须要有一个自己的ID,这个ID在所有进程中都是唯一确定的。客户端在做远程调用时,必须带上这个ID。要实现这个我摩恩就需要在客户端和服务器端分别维护一个函数<—>Call ID的都应表。两者的表不一定要完全相同,只要保证相同的函数对应的Call ID一样即可。当客户端进行远程调用时,它先查这个表中函数对应的Call ID,然后把它传输服务器端,服务器端也通过查表来确定客户端需要调用的函数是哪个,然后执行相应的代码。
  • 第二:序列化和反序列化。在本地调用中,我们只需要把参数压到栈中,然后让函数自己去栈里读就行,但是在远程调用中,不能通过内存来传递参数,甚至有时候客户端和服务器端使用的都不是同一种编程语言。这个时候就需要客户端把参数先转成一个字节流(序列化),传输到服务端后,服务端再把字节流转成自己能读取的格式(反序列化)。同理服务器端返回的值也需要经过序列化和反序列化。
  • 第三:网络传输。远程调用就是用在网络上的不同机器之间,所有的数据都需要通过网络传输。因此需要有一个网络传输层。网络传输层需要把Call ID和序列化后的参数字节流传给服务器,然后再将序列化后的结果传输回来。只要能实现这个功能,都可以作为传输层使用。因此所使用的协议其实是不限制的,只要能完成传输。

 

 

 

 

参考

[1] 谁能用通俗的语言解释一下什么是 RPC 框架? - 知乎 https://www.zhihu.com/question/25536695

[2] RPC简介及框架选择 https://www.jianshu.com/p/b0343bfd216e

你可能感兴趣的:(RPC学习笔记,RPC,原理,RPC框架)