Monday 28 February 2005

分布式系统模式读后记(二)

 

近链接与远链接


 


考虑分布式系统的另外一种方式就是将每个系统视为通过链接连在一起的处理节点的集合。


系统内的链接分成两个部分:


近链接和远连接。


 


近链接:将驻留在同一信任区域中、同一企业内,它们可以以可靠方式连接而且不涉及互操作性。最好使用基于实例的协作。


远链接:包括所有其它连接。最好使用基于服务的协作。


以下都是近链接模式:


 


使用代理(Proxy):代理是与客户端对象通信的对象本身。当客户端创建远程对象的实例时,基础结构就会创建一个代理对象,该对象在客户端看来与远程类型完全相同。当客户端调用该代理对象上的一个方法时,该代理就会调用远程处理的基础结构。远程处理基础结构将请求路由到服务器进程,然后调用服务器对象,并将结果返回给客户端代理,最后客户端代理将结果传递给客户端对象。由于所有这些操作都是在后台进行的,因此客户端对象可能完全不知道另一个对象驻留在其他计算机上。


 


Broker (代理程序)模式描述如何查找远程对象并调用它的一个方法,而不会将通过网络进行通信的复杂性引入应用程序。此模式为大多数分布式体系结构(包括 .NET Remoting)奠定了基础。


 


本地调用:最简单的远程处理模型涉及到按值将对象的副本传递给客户端。以后针对该对象进行的所有方法调用都是真正的本地调用。


 


服务器激活的对象


您拥有对远程对象的引用时,才能调用其上的方法。获取对远程对象的引用要求首先实例化该对象。客户端要求服务器提供该对象的实例,然后服务器返回对远程实例的引用。在无状态服务中,每个请求都会使对象继续保持此前所处的状态。(note:是否保存状态以及如何保存状态还需要和推理机的设计相关啊!!


 


 


有状态的会话:(服务器激活的对象为实例生命期管理仅提供两个替换选项:)


针对每次调用创建对象的新实例。


对于所有客户端仅使用远程对象的单个实例(使该对象有效地成为 Singleton)


感觉这两个解决方案都不能很好的解决我们的对象的生命周期管理的问题。现在的主要问题是,我们需要什么样的生命周期管理????!!


 


客户端激活的对象


客户端激活的对象使客户端能够控制远程对象的生存期。客户端几乎可以像实例化本地对象那样实例化远程对象,在客户端删除对该对象实例的所有引用之后,垃圾回收器会删除远程对象。但是,这种级别的控制成本较高。要使用客户端激活功能,必须复制可由客户端进程访问的程序集。这与各种客户端应该无需进一步设置即可访问远程对象的想法存在冲突。


但是,您可以通过创建一个服务器激活的对象(作为服务器对象的工厂对象)来达到最佳平衡。此工厂对象创建其他对象的实例。工厂本身是没有状态的,因此,您可以很方便地将它作为服务器激活的 Singleton 来实现它。随后,所有客户端请求都共享该工厂的同一个实例。因为该工厂对象在远程运行,所以它所实例化的所有对象都是远程对象,但是客户端可以决定在何时以及在何处实例化它们。(这样就能在有状态和无状态服务中取得折中了:))


 


粗粒度接口:


 


跨进程和网络边界调用方法比调用同一操作系统进程中对象上的方法慢得多。如果使用公开细粒度接口的对象,则会大大影响应用程序的性能,(看来我们有必要重新设计推理机的接口了!!多次提供初始数据的接口调用方法需要重新修正了。)这是由于细粒度接口要求跨进程和网络边界进行多次方法调用。为了改善性能,远程对象必须公开一个粒度更大的接口。粗粒度接口公开一组相对较小的独立方法。每种方法通常都代表一段高级功能(如下订单或更新客户)。因为某个方法所需的全部数据都以参数形式传入该方法中,所以这些方法都被视为独立方法。(这样看来,我们许多设定参数的接口需要整合成一个。定出一个XML的接口标准来。)


 


 


DTOData Transfer Object):


The Data Transfer Object 模式将粗粒度接口概念应用于如下问题在由进程和网络边界隔开的组件之间传递数据。它建议将许多参数替换为一个对象,在该对象中存储远程方法所需的全部数据。该技术对于远程方法返回的数据也非常适用。


三种方案:


1、为解决方案所需的每种不同类型的 DTO 分别定义一个单独的类。针对所包含的每种数据元素,这些类通常有一个强类型的公共字段(或属性)。为了跨网络或进程边界传输这些对象,这些类都要序列化。此方法的主要优点是性能和类型安全。此方法的缺点是需要为每个 DTO 创建一个新类。


 


 


2、是使用一般容器类来保存数据。此方法的常见实现是将类似于 ADO.NET DataSet 的类用作一般容器类。此方法需要两次额外转换。。第一次转换发生在发送端,它将应用程序数据转换为适用于 DataSet 的形式。第二次转换发生在接收端,它将数据从 DataSet 中提取出来以用于客户端应用程序。在某些应用程序中,这些额外的转换可能会影响性能。此方法的另一个不足之处是缺乏类型安全性。如果将客户对象放在发送端的 DataSet 中,则在接收端上尝试提取顺序对象时会导致运行时错误。此方法的主要优点是不必编写、测试或维护任何额外的类。


 


3、类型化 DataSetADO.NET 提供一种自动生成包装 DataSet 的类型安全包装器的机制。此方法存在与 DataSet 方法同样的潜在性能问题,但是应用程序可以受益于类型安全这一优点,并且开发人员不必为每个 DTO 都开发、测试和维护一个单独的类。