分布式编程模式中的租约、事务和分布式事件机制

推荐阅读. 言简意赅,很不错的文章.

原文: http://www.phome.net/e/DoPrint/?classid=8&id=680

Jini 技术面向网络及分布式计算的特性决定了Jini技术必然与传统的单机系统在许多方面有概念上和实际应用中的差别。如网络的延迟、失败,或者设备的突然撤出,将导致信息的无序和丢失;资源的获得、保存、维护和回收情况更为复杂;不同实体之间通讯和协调工作的可靠性及效率并不像单机系统中那样较为容易地获得保证。因而在 Jini 中以 Java 为基础加入了分布式编程模式,特别是引入了租约、分布式事务和分布式事件。

租约


租约的基本概念是资源只能被使用一段时间,这由租约的持有者(lease holder)和租约的授权者(lease grantor)协商决定。

租约接口的目标是为分布式系统和应用程序提供一种特别的编程风格。这种编程风格是当某对象首次对该资源访问时,由这两个对象先协商,最后授权对资源进行某段时间的使用。

在非分布式系统中,资源或服务将被授权直到被明确释放或放弃,这种编程模式在分布式系统中注定要失败,原因是不能保证放弃对资源或系统的使用是肯定成功的,这将导致系统的这部分资源永远不会被释放。

为避免此类问题而引入了租约的概念。在租约中被租用的资源或服务的授权是基于时间的。一旦租借时间期满,服务就将结束,资源将被释放。租约的期限在第一次授权时决定,由租约的授权者和接收者采用request/response方式协商。租约可以在期满前续约或取消。期满时,双方认为服务或资源已回收。

租约概念的引入也可以用于解决分布式系统面临的另一个问题。连续开机的分布式系统趋向于积累过时和不必要的信息,解决这种问题的常规方法是把清理无用资源作为一项系统管理员的任务。然而,当这种资源被租用时,就不会发生过时信息的积累,也不再需要以手工方法清除。租用的信息或资源仅在租约续约时才保存在系统中。因此被遗忘的信息经过有限时间后将被删除。

Jini系统中定义了一组接口以及相关的约定和协议,目的是使不同Java虚拟机通过协商产生各种资源的使用租约。可形成租约的协议有多种,可以分为对某个对象的访问(引用)协议、对未来采取行动(事件通知)的协议和提供长久储存的协议等。租约机制要和并发机制相结合,即某资源可以有多个并发的租约持有者。

租约的特性包括:授权者确保持有者能在一段时间内对资源进行访问;在租约期限内,租约持有者可以取消租约,授权者将清除相关的资源;持有者可以要求续约,续约期限由双方协商决定;若租约到期,授权者将释放相关资源,与取消租约的不同之处在于,授权者与持有者之间不需要通讯。


事务


事务式的行为在分布式计算中尤其重要,它提供了使一个或多个远程参加者对一系列操作的结果保持一致的方法。Jini系统将实现事务语义交由事务中的个体对象处理。系统首先要提供的是对象之间确认事务时用来交换信息的合作机制,目标是提供最小的协议和接口的集合,用以让对象实现事务语义。

Jini描述的完成协议由分布式系统的两阶段提交协议组成。两阶段提交协议定义了分布式对象资源的通讯模式,这个协议需要一个管理者来保证操作集决议的一致性,即保证所有的参加者最终知道它们是应提交操作还是放弃操作。

事务由一个管理者创建和监督,每个事务由一个标识来代表,它对于事务的管理者是唯一的。客户通过一个对管理者的请求来创建事务,通常使用语义工厂类,如Transactionfactory来创建一个语义对象。在对一个服务实行操作时,这个语义对象就将作为一个参数传递。如果服务同意接受这个事务并管理它的操作,它必须作为一个参加者加入到这个事务中去。

如果一个事务成功提交,那么所有在事务之下进行的操作都将完成。放弃事务意味着所有在事务之下进行的操作都如同完全没有发生过一样。提交事务需要每个参加者“表决”,表决可选择“就绪”(准备提交)、“未改变”(只读),或者“放弃”(事务应被放弃)。

两阶段提交协议的设计目标是使对象能够提供ACID属性。缺省的事务语义定义了保留这些属性的一个方法。ACID属性是:

?Atomicity(原子化):所有在一个事务下的操作全部发生或者一个也不发生。

?Consistency(一致性):事务的完成必须使系统保持在一致的状态。事务只是一个使保证一致性成为可能的工具,而它本身并不是一致性的保证者。

?Isolation(隔离性):正在执行的事务不应彼此影响。一个事务的参加者应该只能看到自己事务中操作的中间状态,而不是其它事务的中间状态。

?Durability(耐用性):事务提交的结果应像事务提交的对象实体一样持久,但这个保证只能由对象来完成。

依赖于参加者来实现ACID属性是两阶段提交协议与传统事务处理系统的最大不同之处。两阶段提交协议的定义使用了三个主要类型:

?Transactionmanager??事务管理者创建新的事务并协调参加者的动作。

?NestableTransactionManager??一些事务管理者能够支持嵌套的事务。

?TransactionParticipant??当操作是在一个事务之下进行的,参加者必须加入事务,给管理者提供一个对 TransactonParticipant对象的引用,以便用来表决。


分布式事件


1.分布式事件及通知

分布式事件系统有一些与单机系统不同的特点和需要。由于存在网络延迟和失败的可能性,远程对象事件的通知的顺序可能因客户的不同而异,或者根本没有到达。一个通知到达的时间可能会很长,也可能会有这种情况,接收通知的对象一方不总是希望立即得到通知,而是在接收一方决定的一个确定时间得到。甚至可能发生注册兴趣的对象并不是事件通知应发送的对象。

分布式通知的中心概念是在产生通知的对象和希望接收通知的其他对象之间加入第三方对象。它们可以从对象上卸下通知,实现多种传递保证,存储通知,并进行通知的过滤和重新路由。

2.基本接口和类

Jini 技术中分布式事件的接口定义了一个协议。通过使用该协议,一个Java 虚拟机的对象可以在其他Java 虚拟机对象上注册感兴趣的事件,并在事件发生时得到通知。接口中还规定了这类通知中必须包含的信息。协议中并未体现通知的可靠性与时限,这种保证并非协议的一部分,而是涉及到不同对象的一部分。

2.1涉及到的实体

事件和通知接口定义了实体的基本类型、对提交给实体的信息的需求,及一些支持性接口和类。

分布式系统中基本的对象有:对事件注册感兴趣的对象、发生事件的对象(事件产生者)和事件通知的接收者(远程事件监听者)。

事件产生者有某些其他对象可能会感兴趣的抽象状态,并允许其他对象对此事件注册兴趣。事件发生时,它将产生通知,发送通知到注册过此类事件的事件监听者。

基本类型由RemoteEventListener定义。远程事件监听者对其他对象发生的某类事件感兴趣。一个远程事件监听者的主要功能是接受其他对象中事件发生的通知。

支持性接口和类包括RemoteEvent对象、用作注册标识的EventRegistration对象,及一组可能产生的例外。远程事件是从事件产生者传递到远程事件监听者的对象,用来指示某类特殊事件的发生。EventRegistration类定义了返回注册者需要信息的对象,它是远程事件注册调用的返回值。EventRegistration类的实例包括一个事件类型的标识、当前事件类型的序列号,及一个注册的Lease对象。

保持与远程事件注册模型一致性的接口应反映:

?事件的注册是限定时间的,其方法是使那些注册在需要的时候续约。这可反映为返回一个注册的租约,把它作为事件注册的一部分。

?通知无需传送至最初注册兴趣的实体,即使用第三方过滤器。

?通知可以包含由原始注册者提供的MarshalledObject,使事件通知中能包含任意信息;注册调用应包括MarshalledObjecct以作为RemoteEvent的一部分来传送。

2.2 RemoteEventListener接口

RemoteEventListener是RemoteEvents的接收者。RemoteEventListener由一个只包含一个notify方法的接口来定义。方法将返回注册时导入的信息,允许登记者将任意信息或动作与通知信息关联起来。

RemoteEventListener接口应由希望从其他对象收到 RemoteEvent通知的对象所实现。为使事件发生的通知送至其他对象,注册调用需要接收一个目标参数来指明通知所应送达的对象。

RemoteEventListener接口继承自Remote接口及java.util.EventListener接口。前者说明RemoteEventListener中的方法为远程方法,支持这些方法的对象将通过RMI传递引用。后者用于Java AWT及JavaBeans组件中来指明某个接口是事件通知的接收者。RemoteEventListener接口由一个notify方法组成。

2.3 RemoteEvent类

RemoteEvent对象所包含的的基本形式包括:对发生事件的对象的引用、标识事件类型的长整型、一个指明发生的此类事件的序列号的long,和一个回复的Marshalled Object,它是注册者注册的一部分。这些RemoteEvent的通知对象作为RemoteEventListener对象notify方法的参数传递给 RemoteEventListener。

事件标识及从 RemoteEvent 对象得到的事件发生者引用的组合应唯一确定事件类型。如果此类型并非RemoteEventListener中注册兴趣(或其他代表RemoteEventListener注册)的类型,远程事件监听器的notify方法将抛出 UnknownEventException的例外。

从RemoteEvent对象获得的序列号是一个递增的值,以此来判定远程事件发生的先后顺序。

2.4 EventRegistration类

EventRegistration类的对象用于封装客户所需要的信息,标识出作为注册请求应答的通知,并维护此注册请求。一个允许事件注册的方法并不一定要返回一个EventRegistration类型的对象,但这个类的确包含了在事件模型中需要返回的信息类型。

/document/java/200503/java1110611336681.html

你可能感兴趣的:(分布式计算)