2.1.2 通信的成本
之所以花费那么多篇幅来介绍IPC的手段,是因为最初计算机科学家们的想法,就是将RPC作为IPC的一种特例来看待,这个观点在今天,仅从分类上说也仍然合理,只是到具体操作手段上就不合适了。
请特别注意最后一种基于套接字接口的通信方式(IPC Socket),它不仅适用于本地相同机器的不同进程间通信,由于Socket是网络栈的统一接口,它也能支持基于网络的跨机进程间通信。譬如Linux系统的图形化界面、X Window服务器和GUI程序之间的交互就是由这套机制来实现的。这样做的好处是,由于Socket是各个操作系统都提供的标准接口,完全有可能把远程方法调用的通信细节隐藏在操作系统底层,从应用层面上来看可以做到远程调用与本地的进程间通信在编码上完全一致。事实上,在原始分布式时代的早期确实是奔着这个目标去做的,但这种透明的调用形式反而给程序员带来通信无成本的假象,因而被滥用,以致于显著降低了分布式系统的性能。1987年,在“透明的RPC调用”一度成为主流范式的时候,Andrew Tanenbaum教授曾发表论文“A Critique of The Remote Procedure Call Paradigm”[1],对这种透明的RPC范式提出一系列质问。
·两个进程通信,谁作为服务端,谁作为客户端?
·怎样进行异常处理?异常该如何让调用者获知?
·服务端出现多线程竞争之后怎么办?
·如何提高网络利用的效率?连接是否可被多个请求复用以减少开销?是否支持多播?
·参数、返回值如何表示?应该有怎样的字节序?
·如何保证网络的可靠性?调用期间某个链接忽然断开了怎么办?
·发送的请求服务端收不到回复怎么办?
论文的中心观点是:把本地调用与远程调用当作同样的调用来处理,这是犯了方向性的错误,把系统间的调用透明化,反而会增加程序员工作的复杂度。此后几年,关于RPC应该如何发展、如何实现的论文层出不穷,透明通信的支持者有之,反对者有之,冷静分析者有之,狂热唾骂者也有之,但历史逐渐证明Andrew Tanenbaum的预言是正确的。最终,到1994年至1997年间,由ACM和Sun院士Peter Deutsch、套接字接口发明者Bill Joy、Java之父James Gosling等一众在Sun公司工作的专家们共同总结了通过网络进行分布式运算的八宗罪(8 Fallacies of Distributed Computing)[2]。
1)The network is reliable.——网络是可靠的。
2)Latency is zero.——延迟是不存在的。
3)Bandwidth is infinite.——带宽是无限的。
4)The network is secure.——网络是安全的。
5)Topology doesn’t change.——拓扑结构是一成不变的。
6)There is one administrator.——总会有一个管理员。
7)Transport cost is zero.——不必考虑传输成本。
8)The network is homogeneous.——网络都是同质化的。
以上这八条反话被认为是程序员在网络编程中经常忽略的八大问题,潜台词就是如果远程服务调用要透明化,就必须为这些罪过埋单,这算是给RPC能否等同于IPC来暂时定下了一个具有公信力的结论。至此,“RPC应该是一种高层次的或者说语言层次的特征,而不是像IPC那样,是低层次的或者说系统层次的特征”的观点成为工业界、学术界的主流观点。
在20世纪80年代初期,传奇的施乐Palo Alto研究中心发布了基于Cedar语言的RPC框架——Lupine,并实现了世界上第一个基于RPC的商业应用——Courier,这里施乐Palo Alto研究中心所定义的“远程服务调用”的概念就是完全符合以上对RPC的结论的,所以,尽管此前已经有用其他名词指代“调用远程服务”的操作,一般仍认为RPC的概念最早是由施乐公司提出的。
额外知识
首次提出远程服务调用的定义
远程服务调用是指位于互不重合的内存地址空间中的两个程序,在语言层面上,以同步的方式使用带宽有限的信道来传输程序控制信息。
——Bruce Jay Nelson,Remote Procedure Call,Xerox PARC,1981
[1] 下载地址:https://www.cs.vu.nl/~ast/Publications/Papers/euteco-1988.pdf。
[2] 详见:https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing。