分布式计算编程模型之RPC(2)

Tanenbaum与van Renesse对RPC范式提出了尖锐的批评,他们认为将远程调用与本地调用一视同仁的思想在本质上就是错的,RPC试图打造的透明性也是根本不可能实现的。他们认为为远程访问专门设计一种协议是更好的做法。

Tanenbaum与van Renesse的批评意见涵盖了RFC 684草案中已经提到的几点内容:延迟、缺乏并行性、异常处理以及故障检测等等。此外,他们还提出了一些批评意见:

单线程服务器

如果服务器无法立即向客户端发送响应,比如它正在等待来自另一台服务器的输入。在这种情况下,不仅服务器端产生了阻塞,客户端也无法继续执行本地计算过程。

两军问题

怎样才能让两台服务器对于某个RPC的成功执行以及收到响应的结果达成一致呢?虽然某一方可以向对方发送确认信息,但对方还得向这个确认信息发送另一个确认信息以再次确认。因此无论发送几次确认都无法实现100%的一致性。这一主题其实也是一致性问题的核心,许多与分布式系统相关的文献对其进行了更深入的探讨。

参数

Tanenbaum与van Renesse也叙述了参数传递与参数封送的问题,这一问题在CORBA等有可能包含引用的对象系统中显得更为严重。在这种情况下,为了保证引用的有效性,必须使用某种特定的分布式引用。

幂等性

最后一个问题是如何跨网络表达只执行一次的语义,作者在此处强调了幂等性(idempotence)的重要性。简单来说,具有幂等性的操作即使经过多次执行,其结果与只执行一次也没有区别。举例来说,HTTP中的PUT就具有幂等性的语义,而POST则不具有这一语义。作者提到了一个可能发生的场景:假设服务器在完成某个操作之后突然崩溃而来不及发送确认信息,客户端就有可能在超时之后再次发送这个实际上已经完成的请求,如果此时服务器完成了重启,就有可能再次执行这一操作。而如果该操作不满足幂等性,就可能产生一些意外的副作用。

分布式计算备忘录

Jim Waldo和Sam Kendall等人共同撰写了一篇非常有名的论文“分布式计算备忘录”,这篇论文在Reddit上被人推荐为“每个程序员都应当至少读上两篇”的论文。在这篇论文中,作者表示“忽略本地计算与分布式计算之间的区别是一种危险的思想”,特别指出了Emerald、Argus、DCOM以及CORBA的设计问题。作者将这些设计问题归纳为“三个错误的原则”:

“对于某个应用来说,无论它的部署环境如何,总有一种单一的、自然的面向对象设计可以符合其需求。”

“故障与性能问题与某个应用的组件实现直接相关,在最初的设计中无需考虑这些问题。”

“对象的接口与使用对象的上下文无关”

十年一轮回的错误

Waldo表示,每过10年,人们就会再次尝试将本地计算与远程计算的设计揉合在一起,再一次犯下相同的错误。他再次强调:本地计算与远程计算的本质是完全不同的。

延迟

最明显的区别就在于延迟问题:如果忽略了延迟问题,软件的性能就会受到直接影响。Waldo表示,“依赖于底层硬件速度的逐步提高”是错误的,一些实际的问题是很难通过测试找出的。性能分析是一个复杂的问题,在某一时刻表现良好的设计未必永远是合适的。

内存访问

Waldo对内存访问的批评是特定于CORBA与它的继任者的:对象可能会引用在同一地址空间内的指针,但一旦对象产生了移动,这些指针就会变得无效化。他认为处理这一问题的一种途径是使用分布式共享内存,但在实践上更常见的做法是使用封送或CORBA引用替换技术。

局部故障

作者在最后谈到了一个最本质的问题:局部故障。在本地计算中,故障都是可检测的。而在分布式计算中,相互独立的组件可能会产生故障,并且故障可能是局部的。

舒适感胜于正确性

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/bf9d994f4c06bc9f9b113ca77d3a89dc.html