RPC(二)浅谈RPC

        上一节《RPC(一)简单理解RPC》中曾提到,

“在本地去调用远程机器上的执行(或者叫程序,过程),这个调用过程就是RPC(远程过程调用)。”

        但是这个想法是如何产生的呢?在Nelson的论文中有这么一句话:

远程过程调用(以下称RPC)的概念是非常简单的。它是基于这一观察:过程(或者说程序)调用是一个众所周知且易于理解的机制,用于在单个计算机上运行的程序内的控制和数据的传输。因此提出扩展这种机制以提供跨网络的控制和数据的传输。

        由此可见一斑。

        本篇文章主要介绍RPC的主要目标和最初的理论模型结构。关于为什么这么设计以及更详细的绑定,调用过程请阅读原论文。对于懒得读或者英文较差的同学,本人亲自翻译了一份。但其中有一些我觉得翻译的不够好但又不知道如何改进的地方,恳求大神帮忙。

RPC的目标

        RPC这个概念是在上世纪 80 年代由 Bruce Jay Nelson提出。他设计RPC的最初动机是使得分布式计算更容易。他认为RPC首要的目的是:

使得分布式计算变得容易。能够通过几乎和本地调用程序一样简单轻松的通信机制,消除构造分布式系统的一切不必要的困难。人们将因此被鼓舞去构建并实现分布式应用。

        而为了支持这一目标,还有两个能够支持这一首要目标的次要目标:

1.让RPC通信尽可能的高效。

2.让RPC包的语义尽可能的强大而不能丢失简洁性和有效性。(否则,通过要求应用程序员在RPC包之上构建额外的机制,单一统一通信范式的收益将会丢失。)

        最后,他认为RPC最终最主要的目标是通过RPC提供安全的通信。因为以前实现的协议没有任何保护我们在网络上传输数据的规范,即使密码以明文传输。而且他认为对开放网络进行安全通信的协议和机制的研究已经到到了某个阶段——对他而言把这种保护加入到RPC中是合理且符合期望的。

        但是关于安全加密的实现在参考论文中没有更详细的论述,所以在本篇文章中也不会去讨论这一问题。

RPC的结构

        当发起远程调用时,涉及到五部分程序:user、user-stub、RPC通信包(称为RPCRuntime)、server-stub、server。他们的关系如下图所示。

RPC(二)浅谈RPC_第1张图片
最初的RPC理论模型  

        user,uset-sub和其中一个RPCRuntime的实例在调用者机器上执行;server,server-sub和另外一个RPCRuntime实例在被调用者机器上执行。当user发起远程调用时,其实是执行了一个完全正常的本地调用,而这个调用会去调用user-stub中相应的程序。user-stub负责将目标程序的规范和参数放置在一个或多个包中(打包),并请求RPCRuntime将这些包可靠地传输给被调用者机器。一旦接收到这些包,被调用者机器上的RPCRuntime就这些包传送给server-stub。server-stub将它们解包,像是执行一个完全正常的本地调用一样,该本地调用会调用server中对应的程序。与此同时,调用者机器上的调用进程将被挂起,并等待结果包的返回。当server中的调用完成时,它将结果返回给user-stub打包,然后结果包将由RPCRuntime再传送回给调用者机器上挂起的进程(RCPCRuntime负责重传,确认,数据包路由和加密)。这些包将被user-stub解包并返回给user。

        除去多机器间机器绑定或者通信失败的影响,调用就仿佛user直接在server上调用程序一样。确实是这样,如果user和server的代码放置在同一个机器上,并被直接绑定在一起(无需stub),程序将仍能工作。

        在这五部分中,user和server是需要作为分布式应用的一部分由程序员编写,其他的部分对程序员而言是透明的。user-stub和server-stub是由一个叫Lupine的程序自动生成的。这个生成是通过Mesa接口模块(主要是一系列程序的名称,以及它们的参数类型和结果)指定的。对于调用者和被调用者来说,这已经提供了足够的信息以供它们独立地执行编译时的类型检查并生成合适的调用序列。实现了接口的程序模块被称为导出接口,调用接口过程的程序模块被称为导入接口。当一个程序员想要编写一个分布式应用时,他首先应该编写一组接口模块。然后再去编写导入接口的user code和导出接口的server code。他也应该将接口暴露给Lupine,Lupine将生成user-stub(导出接口)和server-stub(导入接口)。当把程序绑定到调用者机器上时,user即被绑定到user-stub。在被调用者机器上,server-stub也与server绑定。RPCRuntime是Cedar系统(实验者使用的环境)的标准部分。

        因此,程序员不需要去详细地构建那些与通信地址相关的细节代码。设计好接口后,只需要去编写user代码和server代码即可。Lupine负责生成打包和解包参数及结果的代码,以及为Server-stub中接收到的请求调度正确的程序。当然,还有一些问题是需要程序员主动处理的。如:避免指定与缺少共享地址空间不兼容的参数和结果;采取绑定措施;处理机器报告的通信故障等。

一个简单的demo


参考资料

1.BIRRELL, NELSON. [Implementing Remote Procedure Calls]

2.一个简单的代码demo

你可能感兴趣的:(RPC(二)浅谈RPC)