随笔 - 60, 文章 - 0, 评论 - 197, 引用 - 0
数据加载中……

浅析远程过程调用 RPC

一、什么是远程过程调用

  什么是远程过程调用 RPC(Remote Procedure Call)? 你可能对这个概念有点陌生, 而你可能非常熟悉 NFS, 是的,
NFS 就是基于 RPC 的. 为了理解远程过程调用,我们先来看一下过程调用。

  所谓过程调用,就是将控制从一个过程 A 传递到另一个过程 B, 返回时过程 B 将控制进程交给过程 A。目前大多数系统
中, 调用者和被调用者都在给定主机系统中的一个进程中, 它们是在生成可执行文件时由链接器连接起来的, 这类过程调用称
为本地过程调用。

  远程过程调用(RPC)指的是由本地系统上的进程激活远程系统上的进程, 我们将此称为过程调用是因为它对程序员来说表现
为常规过程调用。处理远程过程调用的进程有两个, 一个是本地客户进程, 一个是远程服务器进程。对本地进程来说, 远程过
程调用表现这对客户进程的控制, 然后由客户进程生成一个消息, 通过网络系统调用发往远程服务器。网络信息中包括过程调
用所需要的参数, 远程服务器接到消息后调用相应过程, 然后将结果通过网络发回客户进程, 再由客户进程将结果返回给调用
进程。因此, 远程系统调用对调用者表现为本地过程调用, 但实际上是调用了远程系统上的过程。


二、远程过程调用模型

  本地过程调用: 一个传统程序由一个或多个过程组成。它们往往按照一种调用等级来安排。如下图所示:


  远程过程调用: 使用了和传统过程一样的抽象, 只是它允许一个过程的边界跨越两台计算机。如下图所示:


三、远程过程和本地过程的对比

  首先, 网络延时会使一个远程过程的开销远远比本地过程要大
  其次, 传统的过程调用因为被调用过程和调用过程运行在同一块内存空间上, 可以在过程间传递指针。而远程过程不能够将
指针作为参数, 因为远程过程与调用者运行在完全不同的地址空间中。
  再次, 因为一个远程调用不能共享调用者的环境, 所以它就无法直接访问调用者的 I/O 描述符或操作系统功能。


四、远程过程调用的几种版本 
  (1) Sun RPC (UDP, TCP)
  (2) Xerox Courier (SPP)
  (3) Apollo RPC (UDP, DDS)

  其中 Sun RPC 可用于面向连接或非面向连接的协议; Xerox Courier 仅用于面向连接的协议; Apollo RPC 仅用于非连接的协议
 

五、如何编写远程过程调用程序
 
  为了将一个传统的程序改写成 RPC 程序, 我们要在程序里加入另外一些代码, 这个过程称作 stub 过程。我们可以想象一
个传统程序, 它的一个过程被转移到一个远程机器中。在远程过程一端, stub 过程取代了调用者。这样 stub 实现了远程过
程调用所需要的所有通信。因为 stub 与原来的调用使用了一样的接口, 因此增加这些 stub 过程既不需要更改原来的调用过
程, 也不要求更改原来的被调用过程。如下图所示:

 


六、示例
    此示例在 Ubuntu 8.04 + gcc 4.2.3 下编译运行通过。

    远程过程调用示例(点击下载)

posted on 2008-08-15 17:02 Normandy 阅读(14418) 评论(12)  编辑 收藏 引用 所属分类: Networking

评论

# re: 浅析远程过程调用 RPC[未登录]  回复  更多评论   

RPC的优势在哪里?
2008-08-15 17:56 | achilles

# re: 浅析远程过程调用 RPC  回复  更多评论   

@achilles
优点是可直接访问远程过程,避免烦琐的打包和解包过程,且不依赖于某种特定的协议
2008-08-15 18:40 | Normandy

# re: 浅析远程过程调用 RPC[未登录]  回复  更多评论   

@Normandy
可是这些过程为什么非要放到不同的机器呢,与普通的网络通信相比RPC有什么优势?
2008-08-15 20:38 | achilles

# re: 浅析远程过程调用 RPC  回复  更多评论   

@achilles
优点是可直接访问远程过程,避免烦琐的打包和解包过程,且不依赖于某种特定的协议
===================
显然你就是看的皮毛
底层仍然通过打包解包实现
你没听说过marshall这个词?
这只不过是打包的另一种说法罢了。。。
2008-08-15 21:05 | 访客

# re: 浅析远程过程调用 RPC  回复  更多评论   

远程过程调用的使用领域太广泛了,以后要是能不联机就能定时生成或采集数据就更好了。
2008-08-17 17:46 | dell笔记本

# re: 浅析远程过程调用 RPC  回复  更多评论   

@achilles
将一些过程放在远程是分布式程序的要求,如客户机/服务器模式。相比常规的网络通信程序而言,在用 RPC 时我们只需要关心程序本身的逻辑,就像建本地程序一样,因为 RPC 已经帮你做了网络通信的工作!

如果你还是不能理解, 请下载我上面的远程过程调用示例,将客户程序和服务程序放在两个不同的机器上运行看看。

如果你想了解更多的细节,请看一下 <<Linux 网络编程>> 第十二章,上面的内容更精彩!
2008-08-18 10:13 | Normandy

# re: 浅析远程过程调用 RPC  回复  更多评论   

[荐]RPC is bad?
偶像 Steve Vinoski 在 maillist 的回帖中一不留神就泄漏了他为 ErlangeXchange 准备的 session ,我们可以先一睹为快。Steve 大拿是 CORBA 界的牛人,对 RPC 是 bad 很有发言权地。这篇文章也写得很漂亮,水分相当少,我就不干“损失味道”的事情了。
为方便阅读,将 mail 内容盗版如下:
Well, if you had time you could dig through my various IEEE Internet Computing columns from the past 6 years and find many reasons listed there. For example, “RPC Under Fire“(note that it’s PDF) from the Sep/Oct 2005 lists a number of problems:
Also, pretty much any of my columns that cover REST to any degree would also contain mentions of RPC’s shortcomings. All the columns can be found here:
But if you don’t have the time or energy, the fundamental problem is that RPC tries to make a distributed invocation look like a local one. This can’t work because the failure modes in distributed systems are
quite different from those in local systems, so you find yourself having to introduce more and more infrastructure that tries to hide all the hard details and problems that lurk beneath. That’s how we got
Apollo NCS and Sun RPC and DCE and CORBA and DSOM and DCOM and EJB and SOAP and JAX-RPC, to name a few off the top of my head, each better than what came before in some ways but worse in other ways, especially footprint and complexity. But it’s all for naught because no amount of infrastructure can ever hide those problems of distribution. Network partitions are real, timeouts are real, remote host and service
crashes are real, the need for piecemeal system upgrade and handling version differences between systems is real, etc. The distributed systems programmer *must* deal with these and other issues because
they affect different applications very differently; no amount of hiding or abstraction can make these problems disappear. As I said about such systems in a recent column:
“The layers of complexity required to maintain the resulting leaky illusion of local/remote transparency are reminiscent of the convoluted equations that pre-Copernican astronomers used to explain how the Sun and other planets revolved around the Earth.” (from “Serendipitous Reuse“)
RPC systems in C++, Java, etc. also tend to introduce higher degrees of coupling than one would like in a distributed system. Typically you have some sort of IDL that’s used to generate stubs/proxies/skeletons
2008-08-21 00:56 | 访客

# re: 浅析远程过程调用 RPC  回复  更多评论   

code that turns the local calls into remote ones, which nobody wants to write or maintain by hand. The IDL is often simple, but the generated code is usually not. That code is normally compiled into each app in the system. Change the IDL and you have to regenerate the code, recompile it, and then retest and redeploy your apps, and you typically have to do that atomically, either all apps or none, because versioning is not accounted for. In an already-deployed production system, it can be pretty hard to do atomic upgrades across the entire system. Overall, this approach makes for brittle, tightly-coupled systems.
Such systems also have problems with impedance mismatch between the IDL and whatever languages you’re translating it to. If the IDL is minimal so that it can be used with a wide variety of programming
languages, it means advanced features of well-stocked languages like Java and C++ can’t be used. OTOH if you make the IDL more powerful so that it’s closer to such languages, then translating it to C or other
more basic languages becomes quite difficult. On top of all that, no matter how you design the IDL type system, all the types won’t — indeed, can’t — map cleanly into every desired programming language. This turns into the need for non-idiomatic programming in one or more of the supported languages, and developers using those languages tend to complain about that. If you turn the whole process around by using a programming language like Java for your RPC IDL in an attempt to avoid the mismatch problems, you find it works only for that language, and that translating that language into other languages is quite difficult.
There’s also the need with these systems to have the same or similar infrastructure on both ends of the wire. Earlier posters to this thread complained about this, for example, when they mentioned having to have CORBA ORBs underneath all their participating applications. If you can’t get the exact same infrastructure under all endpoints, then you need to use interoperable infrastructure, which obviously relies on interoperability standards. These, unfortunately, are often problematic as well. CORBA interoperability, for example, eventually became pretty good, but it took about a decade. CORBA started out with
no interoperability protocol at all (in fact, it originally specified no network protocol at all), and then we suffered with interop problems for a few years once IIOP came along and both the protocol itself and implementations of it matured.
Ultimately, RPC is a leaky abstraction. It can’t hide what it tries to hide, and because of that, it can easily make the overall problem more difficult to deal with by adding a lot of accidental complexity.
In my previous message I specifically mentioned Erlang as having gotten it right. I believe that to be true not only because the handling of distribution is effectively built in and dealt with directly, but also because Erlang makes no attempt to hide those hard problems from the developer. Rather, it makes them known to the
developer by providing facilities for dealing with timeouts, failures, versioning, etc. I think what Erlang gives us goes a very long way and is well beyond anything I’ve experienced before. Erlang really doesn’t provide RPC according to the strict definition of the term, BTW, because remote calls don’t actually look like local ones.
(BTW, this is the kind of stuff I’ll be talking about at Erlang eXchange next month.)
2008-08-21 00:57 | 访客

# re: 浅析远程过程调用 RPC  回复  更多评论   

可不可以这样理解:
通常的C/S程序,Server端的程序必须已经在运行,Client端的程序才能和它通讯。

而使用RPC,Client可以远程启动Server端的程序。
2008-09-07 10:41 | 访客

# re: 浅析远程过程调用 RPC  回复  更多评论   

你讲得非常棒,看了你的文章,让我知道了什么RPC。
2009-03-15 15:12 | bob.shao

# re: 浅析远程过程调用 RPC  回复  更多评论   

虽然RPC有好有不好,不过很赞你的文章看了就懂,而且跟着做就可以简单理解一下rpc的例子。

RPC虽然对网络依赖,但是对于中间件技术来说还是蛮赞的技术。
2009-12-03 21:06 | kaholi

# re: 浅析远程过程调用 RPC  回复  更多评论   

你将得非常的好.谢谢你
2014-12-01 19:06 | 被JAVA淹没的库比程序员

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理