远程服务最常见的形式之一是RPC方式,RPC被设计成一种抽象过程调用机制,用于在具有网络连接的系统之间进行使用。

RPC在很多方面与IPC(进程间通信)相似,而且它通常建立在这样一个系统之上。

因为在所处理的环境中,进程在不同的系统上执行,所以我们必须使用基于消息的通信机制来提供远程服务。

与IPC消息比起来,在RPC通信中交换的消息有很好的结构,因此不再仅仅是数据包。每个消息都被发送到一个RPC守护进程/后台程序,该守护进程/后台程序监听远程系统上的一个端口,每个消息都包含一个指定要执行的函数的标识符,以及传递给该函数的参数。然后按请求执行指定的函数,并且任何输出都会以单独的消息发送回请求者。

端口(port)仅仅是一个包含在消息包开始的数字。一个系统通常有一个网络地址。在该地址中,它可以有许多端口,以区分它所支持的许多网络服务。

如果一个远程进程需要一个服务,它将消息发送到适当的端口。

RPC的语义允许客户机在远程主机上调用过程,就好像在本地调用一个过程一样。

RPC系统隐藏了通过在客户端提供存根(stub)来进行通信的细节。

通常,每个独立的远程过程都存在一个单独的存根。当客户端调用远程过程时,RPC系统调用适当的存根,将参数传递给远程过程。

该存根定位服务器上的端口,并对参数进行编组(marshals)。参数编组包括将参数打包成可以通过网络传输的表单。然后存根通过消息传递向服务器传递消息。

服务器端的一个类似的存根接收此消息并调用服务器上的过程。

如果需要,返回值将使用相同的技术返回给客户端。在Windows系统上,存根代码是从Microsoft Interface Definition Language (MIDL)中编写的规范编译的,该规范用于定义客户机和服务器程序之间的接口。

必须处理的一个问题是客户端和服务器机器上的数据表示方面的差异。考虑一个32位整数的表示。有的系统使用高内存地址存储高字节(称为大端,big-endian),而有的系统则使用高内存地址存储低字节(称为小端,little-endian).

为了解决这样的差异,许多RPC系统定义了与机器无关的数据表示。一种这样的数据表示是 外部数据表示法 ( external data representation,XDR )。在客户端,参数编组涉及将机器依赖的数据在发送到服务器之前转换为XDR。在服务器端,XDR数据被解编组,并转换为服务器的机器依赖的数据表示。

另一个重要的问题涉及到调用的语义。尽管本地过程调用只在极端情况下失败,但是RPCs可能会因为常见的网络错误而失败,或者多次重复执行。解决这个问题的一种方法是操作系统来确保消息只执行一次(exactly once),而不是最多执行一次(at most once)。绝大部分的本地过程调用都具有只执行一次(exactly once)的功能,但是很难实现。

首先考虑最多执行一次(at most once)。这个语义可以通过为每个消息附加一个时间戳来实现。服务器对于其所处理的消息,必须有一个完整的或者足够长的时间戳历史,以确保能检测到重复消息。已经在历史上有时间戳的传入消息被忽略了。然后客户端可以发送一个或多个消息,并确保它只执行一次。

对于只执行一次(exactly once),我们需要消除服务器永远不会收到请求的风险。为了实现这一点,服务器必须实现上面描述的最多执行一次(at most once)协议,但还必须向客户端确认收到并执行了RPC调用。这些ACK消息在网络中很常见。客户端必须定期重新发送每个RPC调用,直到接收到该调用的ACK为止。

另一个重要的问题涉及服务器和客户机之间的通信。通过标准的过程调用,在链接、加载/装入或执行时间(第8章)中会发生某种形式的绑定,这样,过程调用的名称就会被过程调用的内存地址所取代。RPC方案需要有一个类似于客户机和服务器端口的绑定,但是客户机如何知道服务器上的端口号呢?两个系统都没有关于另一个系统的完整信息,因为它们不共享内存。

对此有两种方法:

  • 绑定信息可能预定义的,以固定的端口地址的形式。在编译时,RPC调用有一个与之相关联的固定端口号。一旦程序被编译,服务器无法更改所请求服务的端口号。
  • 绑定可以通过一个集合点( rendezvous)机制来动态完成。通常,操作系统在一个固定的RPC端口上提供一个集合点(也称作matchmaker)守护进程/后台程序。然后,客户端会发送包含RPC名称的消息给集合点守护进程/后台程序,以请求需要执行的RPC的端口地址。端口号被返回,并且RPC调用可以被发送到那个端口,直到进程终止(或者服务器崩溃)。这种方法需要初始请求的额外开销,但是比第一个方法更灵活。图3.23显示了一个示例交互。

RPC方案在实现分布式文件系统时非常有用。这样的系统可以通过一组RPC守护进程/后台程序和客户端来实现。消息被发送服务器上的文件系统端口以进行文件操作。消息中包含要执行的磁盘操作。这些磁盘操作可能hiread,write,rename,delate或者是status,对应于通常的文件相关的系统调用。返回消息包含来自该调用的任何数据,该调用由DFS守护进程代表客户机执行。例如,消息可能包含将整个文件传送到客户端或被限制为一个简单的块请求的请求。在后一种情况下,如果要传输整个文件,可能需要几个请求。

results matching ""

    No results matching ""