本文摘抄自PoEAA,详细信息请阅读本书
7.1 分布对象的诱惑
透明性非常有用,但虽然有很多东西在分布对象中可以是透明的,但性能却不在其中,尽管上面的架构师是为了提高性能而使用分布组件的,但他的设计只会影响性能,使系统难以构建或部署。
7.2 远程接口和本地接口
按类模型进行分布的方法不可行的主要原因与计算机的基本特点有关,进程内的过程调用非常快,两个独立进程间的过程调用就慢了一个数量级,不同机器间的过程调用又慢了一两个数量级。
本地接口最好是细粒度接口,但细粒度接口不能很好的用在远程调用中,当方法调用很慢时,应该把三次调用合并到一次调用的粗粒度接口,一旦某个对象会被远程访问到,就应该使用粗粒度接口,虽要付出更大的编程代价。显然,只有必要时才应该这么做,应该最小化夸进程的对象协作的数量。
分布对象设计的第一定律:不要分布使用对象。
那么如何有效利用多处理器资源呢?大多数情况下是使用集群系统,这样一来,每个处理器上的对象只会用到本地调用,从而运行更快。
7.3 必须使用分布的情况
总有一些需要分布到不同进程的情况。
- 客户机与服务器的划分是典型的跨进程划分
- 第二种划分出现在基于服务器的应用软件和数据库之间。
- 另一个进程划分出现在Web服务器与应用服务器之间的Web系统中,最好是在同一进程中运行Web服务器与应用服务器。
- 还可能由于厂商的不同而划分,使用的软件包可能需要在单独的进程中运行,这又会用到分布,至少一个好的软件包提供粗粒度的接口
- 最后,还可能有一些别的原因导致你必须去划分你的应用服务器软件。
7.4 关于分布边界
在设计系统时必须尽可能限制分布边界,但在必要的地方还得考虑他们,系统中每个地方都应极力减少远程调用,这样才能使性能开销最小。
然而,还是可以在一个进程内使用细粒度对象进行设计。关键记住只在进程内部使用他们,而在分布边界上放置粗粒度对象,它们唯一的目的是去提供一个到细粒度对象的远程接口,粗粒度对象实际上不做任何事情,从而充当细粒度对象的外观。这个外观只为分布需要而使用——因此称为远程外观。
使用远程外观能减少粗粒度接口引入的困难,这样那些真正需要远程服务的对象才使用粗粒度接口,这也使开发人员清楚所付出的代价,透明有它的好处,但不要期待一个潜在的远程调用透明。
然而,让粗粒度接口仅仅作为外观,可以让使用者无论何时只要他们知道自己运行于同一进程中就使用细粒度对象,这使得分布策略非常明显。通常和远程外观一起使用的还有DTO。因为不止是需要粗粒度的方法,还需要传输粗粒度的对象,当请求一个地址时,需要将信息放在一个数据块中发送出去。通常不能把领域对象本身直接发送出去,因为它们绑定到一个由细粒度的本地对象间引用组成的网络中。所以,应该将客户端需要的所有数据打包在一个特定的对象中,以便于传输,就成了所谓的DTO。传输双方都用到了D TO,很重要的就是要保证它们不能引用网络间任何共享的事物。事实上,一个DTO一般只引用其他的DTO和一些字符串等原始类型的对象。
运行分布的另一方式是使用一个代理在进程间迁移对象,这个思想用到了延迟加载方案来传递对象,不是用数据库的延迟读而是在网络之间移动对象。最困难的部分在于:要保证结果不会产生太多的远程调用,我没有看到谁真的在应用中使用这种方式,但用在一些O/R映射工具中,传来了一些较好的评价。
7.5 分布接口
由于历史原因,分布组件的接口都基于远程过程调用RPC。
还有一种将XML作为数据传输对象的方式。Web Service在不同平台相互交互时能提供便利,建议在无法使用更直接的方法时才使用Web Service。
所有到Web服务器的调用都被Http协议传给底层的面向对象接口处理,这在一定程度上能取得两者的长处,但由于需要Web服务器和主机远程面向对象接口,从而增加了系统复杂度,因此,应该在同时需要使用Http协议和远程面向对象的API时,或者在安全的事务处理机制的远程面向对象API的设施能比使用本地对象更容易地处理这些问题时才能使用这种方法。
我们已经假定了一个同步的,基于PRC接口的,虽然如此,我并不认为这这总是进行分布的最佳方法。逐渐地,我的偏好转向了基于消息的处理方式(它在本质上是异步的)。虽然看在的很多例子都是基于同步处理的,但我认为在Web Service中更适合使用异步方式。