不仅仅是 CORBA,一般来说它是 RPC。这包括 DCOM、Java-RMI、.NET Remoting 和所有其他的东西。
问题基本上在于分布式计算从根本上不同于本地计算。 RPC 试图假装这些差异不存在,并使远程调用看起来就像本地调用一样。但是,为了构建一个好的分布式系统,您需要处理这些差异。
Bill Joy、Tom Lyon、L. Peter Deutsch 和 James Gosling 确定了分布式计算的 8 个谬误,即分布式编程的新手认为是正确的,但实际上是错误的,这通常导致项目失败或成本和工作量显着增加。 RPC 是这些谬误的完美体现,因为它建立在同样的错误假设之上:
- 网络可靠。
- 延迟为零。
- 带宽是无限的。
- 网络安全。
- 拓扑不会改变。
- 只有一名管理员。
- 运输成本为零。
- 网络是同构的。
所有这些都适用于本地计算。
以可靠性为例:如果您在本地调用一个方法,那么调用本身总是会成功。当然,被调用的方法本身可能有错误,但是方法的实际调用总是会成功的。并且始终会返回结果,或者,如果方法失败,则会发出错误信号。
在分布式系统中,情况并非如此:调用方法本身的行为可能会失败。 IE。从您的角度来看,您似乎调用了该方法,但该调用实际上在网络上丢失了并且从未到达该方法。或者,该方法成功接收到调用并执行了操作,但结果在返回给您的途中丢失了。或者方法失败了,但是错误丢失了。
与延迟类似:在本地,调用方法基本上是免费的。方法本身可能需要任意时间来计算答案,但调用是免费的。通过网络,一个呼叫可能需要数百毫秒。
这就是几乎所有 RPC 项目(包括 CORBA)都失败的原因。
请注意,反过来也可以:如果您只是假装所有调用都是远程调用,那么可能发生的最糟糕的事情就是您丢失了一个一点点性能,你的应用程序包含一些永远不会使用的错误处理代码。例如,这就是 Erlang 的工作原理。
在 Erlang 中,进程总是有单独的堆和单独的垃圾收集器,就像它们运行在不同大陆的不同机器上一样,即使这些进程在同一个 CPU 上的同一个 VM 上运行相同的地址空间。如果您将数据从一个进程传递到另一个进程,则该数据始终会被复制,就像进程位于不同机器上时一样。调用总是作为异步消息发送进行。
因此,使本地和远程调用看起来相同不是问题。让它们看起来像本地调用。
在 CORBA 中,问题实际上比这更令人费解。他们实际上确实使本地调用看起来像远程调用,但是由于 CORBA 是由委员会设计的,远程调用难以置信复杂,因为它们必须能够处理一些难以置信的荒谬要求。这种复杂性被强加给每个人,即使是本地电话也是如此。
再次,与 Erlang 相比,复杂性要低得多。在 Erlang 中,向进程发送消息并不比在 Java 中调用方法复杂。接口基本相同,只是期望不同:Java中的方法调用期望是瞬时的和同步的,而在Erlang中,消息发送期望是异步的并且具有可见的延迟。但实际上使用它们并不比一个简单的本地过程调用更复杂。
另一个区别是 Erlang 区分了函数调用和消息发送,它只能发生在进程内部,因此总是本地的,消息发送发生在进程之间,并且假定总是远程的,即使它们不是。在 CORBA 中,所有方法调用都被假定为远程的。