操作系统 - 远程过程调用 (RPC)
远程过程调用 (RPC) 是一种用于客户端-服务器应用程序的进程间通信技术。它也被称为子程序调用或函数调用。阅读本章以了解更多关于远程过程调用及其工作原理的内容。
远程过程调用做什么?
客户端有一个请求消息,RPC 会将其翻译并发送到服务器。此请求可能是对远程服务器的 process 或 function 调用。当服务器收到请求时,它会将所需的响应发送回客户端。在服务器处理调用期间,客户端会被阻塞,仅在服务器完成处理后才恢复执行。
RPC 允许程序调用位于另一台机器上的 function,它的工作方式就好像该 function 在本地系统上运行一样。在 RPC 中,所有网络通信(如数据传输(发送请求和接收响应)和协议处理等)都对用户隐藏。因此,RPC 是一种行为如同本地函数调用的远程调用。
RPC 用于分布式系统和客户端-服务器通信,其中一台系统/计算机需要运行存在于通过网络连接的另一台计算机上的 function。RPC 的主要目的是隐藏所有网络通信信息,并使存在于两个不同系统中的程序更容易相互通信。
RPC 的工作过程
下图展示了 RPC 的工作概述 —
远程过程调用中的事件序列如下所示 —
- 客户端调用客户端 Stub — 客户端调用客户端 stub(本地过程)。
- 客户端 Stub 打包(Marshalling)参数 — 客户端 stub 进行系统调用以将消息发送到服务器,并将参数放入消息中。
- 发送到服务器 — 消息由客户端的操作系统从客户端发送到服务器。
- 服务器接收消息 — 消息由服务器操作系统传递到服务器 stub。
- Stub 解包参数 — 服务器 stub 从消息中移除参数。
- 服务器运行过程 — 然后,服务器 stub 调用服务器过程。
注意: stub 是一小段代码,充当客户端和服务器之间的接口,并处理它们之间的所有通信。
RPC 类型
RPC 有多种类型。在本节中,我们将简要了解一些常见的 RPC 类型。
同步 RPC
也称为 阻塞 RPC,在此情况下,客户端向服务器发送请求并等待服务器响应。客户端被阻塞,直到 RPC 完成才能够继续其任务。
异步 RPC
客户端向服务器发送请求,但不等待服务器响应,而是继续执行其任务。它速度快,客户端可以自由继续其任务。也称为 非阻塞 RPC。
回调 RPC
回调 RPC 是一种远程过程调用,其通信是双向的。客户端首先向服务器发送请求,服务器完成任务后,会通过另一个 RPC 调用回客户端。通过这种 callback,服务器可以在不等待客户端查询的情况下通知客户端结果或更新。
回调 RPC 常用于实时通知,以及服务器需要向客户端发送信息的应用程序。
批量 RPC
批量 RPC 是一种远程过程调用,其中多个 RPC 请求被组合在一起,以单个消息发送到服务器。客户端不是逐个发送小请求,而是作为一批发送。这减少了网络开销。
当需要同时执行多个远程调用且客户端不需要立即获取请求响应时,批量 RPC 非常有用。
广播 RPC
广播 RPC 是一种远程过程调用,其中客户端同时向网络中的所有服务器发送单个请求。请求不是发送到特定服务器,而是被广播,每个接收到请求的服务器可以决定是否响应或忽略客户端请求。
当客户端不知道哪个服务器拥有所需信息时,广播 RPC 非常有用。例如,在分布式系统中定位资源。由于它会广播请求,这种 RPC 类型可能会产生大量网络流量,因为客户端请求同时发送到所有服务器。
远程过程调用的组件
让我们来看看 RPC 的主要组件 −
- Client − 客户端是请求服务的程序。它进行函数调用,而无需知道该函数运行在另一个系统上。
- Server − 服务器是接收并执行客户端函数调用的程序。
- Client Stub − 客户端存根作为客户端和服务器之间的接口。它接收来自客户端的函数调用,将其转换为请求消息并发送到服务器。
- Server Stub − 服务器存根接收来自客户端的请求,从该请求中分离出所需数据,并调用服务器函数来执行请求的服务。任务完成后,将响应发送回客户端。
- RPC Runtime − 它帮助管理客户端和服务器之间的通信。
- Network − 网络连接客户端和服务器机器。它帮助在客户端和服务器机器之间传输请求和响应消息。
- Binding − 它帮助客户端找到确切的服务器名称,以确定提供请求服务的服务器的网络地址。
使用 RPC 的问题
本地过程调用仅在极端情况下才会失败,而 RPC 可能会失败,或者被重复并执行多次。因此,它可能会导致网络错误。
在标准过程调用中,某些binding会在链接、加载和执行时进行,这样过程调用名称会被替换为过程调用的内存地址。RPC 也需要类似 client 和 server port 的绑定。但是 client 如何知道 server 上的端口号呢?这种情况出现是因为没有系统拥有关于其他系统的完整信息,因为它们不共享内存。
现在让我们了解如何解决这些问题 −
操作系统必须确保消息被精确处理一次。大多数本地过程调用具有“精确一次”功能。但是,在 RPC 中,实现起来更困难,因为消息通过网络传输,因此可能会丢失或重复。
绑定信息可以预先确定,以固定端口地址的形式。在编译时,一个 RPC 调用与固定的端口号相关联。一旦程序编译完成,server 就无法更改所请求服务的端口号。但这种解决方案不够灵活,因为端口号必须固定,如果我们想更改端口号,就无法做到。
绑定可以通过rendezvous mechanism动态进行。在这种机制中,操作系统在固定的 RPC 端口上提供一个rendezvous (matchmaker) daemon。client 向 rendezvous daemon 发送包含 RPC 名称的消息,请求它需要执行的 RPC 的端口地址。端口号会被返回,RPC 调用可以发送到该端口,直到进程终止或 server 崩溃。这里,我们不需要固定端口号,因为 matchmaker 总是能找到特定 procedure 名称的端口号并将其返回给 client。
使用 RPC 的优缺点
RPC 提供了以下优势 −
- RPC 支持面向进程和面向线程的模型。
- RPC 的内部消息传递机制对用户隐藏。
- 在 RPC 中,重写和重新开发代码的努力最小。
- RPC 可以在分布式环境以及本地环境中使用。
- RPC 省略了许多协议层以提高性能。
RPC 的有些缺点如下 −
- RPC 是一个可以以不同方式实现的概念。它不是一个标准。
- RPC 在硬件架构上没有灵活性。它仅基于交互。
RPC 与 REST
RPC 和 REST 是两种不同的方式,让计算机程序在 Internet 上相互交互。下表突出了 RPC 与 REST 的区别 −
| RPC (Remote Procedure Call) | REST (Representational State Transfer) |
|---|---|
| RPC 允许程序调用位于另一台机器上的函数,它的工作方式就像该函数在同一系统上本地运行一样。 | REST 允许 client 通过 HTTP 请求与 server 上的数据交互。 |
| RPC 用于在远程系统上执行过程或函数。 | REST 用于访问、创建、更新和删除资源。 |
| 在 RPC 中,通过 server 定义的函数或方法调用进行通信。 | 在 REST 中,通过 URL 和 HTTP 方法如 GET、POST、PUT 和 DELETE 进行通信。 |
| RPC 可以使用不同的数据格式,如 JSON、XML 和 binary formats。 | REST 也使用不同的数据格式如 JSON、XML 来表示 client 和 server 之间发送的数据。 |
| RPC 可以用在不同的通信协议上,如 TCP、HTTP、UDP、HTTP 等。 | 但 REST 只能用在 HTTP 协议上。 |
| RPC 用于内部系统和高性能应用。 | REST 广泛用于 web API、移动应用和公共服务。 |
结论
远程过程调用(Remote Procedure Call)为运行在不同系统上的程序提供了一种通过网络相互通信的方式。它允许程序调用远程机器上的函数。它向用户隐藏了网络通信的过程。RPC 在分布式系统中被广泛使用。