Java开发网 Java开发网
注册 | 登录 | 帮助 | 搜索 | 排行榜 | 发帖统计  

您没有登录

» Java开发网 » Design Pattern & UML  

按打印兼容模式打印这个话题 打印话题    把这个话题寄给朋友 寄给朋友    该主题的所有更新都将Email到你的邮箱 订阅主题
flat modethreaded modego to previous topicgo to next topicgo to back
作者 EJB设计模式之message facade
Pcman



发贴: 0
积分: 0
于 2002-07-24 14:45 user profilesend a private message to usersearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
message facade

一个ejb客户端想要在一个环境的用例中调用多个ejb的方法,并且不需要从服务器的立即的反映。

怎样才能让ejb客户端在一个事务中调用多个session bean或entity bean的方法,不需要被阻塞并且等待每个bean的反映?

特别在大型系统中,伸缩性指明一个用例的商业逻辑与客户端的分离执行,不需要客户端等待执行完毕。这种类型的行为,叫做异步行为,允许客户端用最大的反应时间和用户界面(UI)交互,因为他们不需要坐下来等待他们启动的用例执行。这种方法允许大型系统伸缩,因为用例能在一个批处理中排队并被执行,对用户透明,用户可以马上转移到UI的下一个部分。如果排队的用例的大部分已经开始发展,系统执行用例的部分也能被伸缩并且通过系统升级,都不需要改变对客户端的可用性和质量。

考虑一个简单的基于web的航线注册系统,在这个系统中一个servlet接受为一个用户的特定的一个航班预定一个座位的请求。在这种场景中,一个servlet必须用一个航线注册一个用户,决定如果座位在一次航班上是否可用,为一个用户预定一个座位,如图1.5所示。

在这个例子中,我们有一个客户端为了执行一个用例完成对服务器的多个异步调用。这个过程的每一步需要一个分离的网络调用并阻塞客户端的部分。在一个像航线预定应用一样巨大的系统中,这个瓶颈显然是无法接受的。还有,在这样的风格下执行逻辑减少了系统的可维护性和可重用性,并且不为用例提供事务的一致性和分离性。

最通常的解决方案是使用session facade模式。用这个模式,一个应用程序创建一个包含充满商业用例的商业逻辑的session bean层。每个session bean在一个大块(bulk)调用中代表客户端完成对entity bean或其他服务器端资源的大块(bulk)操作,如session facade模式的图1.3所示。不幸的是,即使整个用例是被session facade方法封装,这个方法仍然有以下几个缺点:

1.无法接受的反应时间。一个和web站点交互的用户将不能等待数秒以上。这个用例的执行需要能扩展不同的航线系统的多个数据库的很多背景进程。因为对ejb层的调用是一个同步调用,客户端将被阻塞直到整个过程结束。

2.不可靠/无容错机制。这个用例能潜在的涉及分布在3个分离的ejb服务器的ejb和3个分离的数据库(一个为用户,一个为航线,一个为航班)。如果任何这些服务器中的一个当机了,整个过程将会失败,并且用户的预定请求将会丢失。即使如果servlet层和只有一个ejb服务器通信,如果服务器当掉了,过程也将失败。

使用session facade解决耦合,性能,可维护性,可重用性,和一致性的问题,但不能完全解决反应和可靠性的问题。当一个复杂和耗费时间的预定用例运行,客户端仍将只得被阻塞。如果ejb服务器或任何它依赖的系统在用例执行时没有运行,那么用例也会失败。

我们的讨论的结论是我们需要一个有容错机制的服务器端抽象,它作为一个中介,在一个调用和一个事物中执行用例(保护客户端不受服务器端对象模型的复杂性的影响),不需要客户端被阻塞并等待用例完毕。Message-driven beans是专门为这个设计的。

综上所述:
使用message-driven bean去创建一个容错的,异步的facade。客户端应该只存取message-driven bean, 不存取entity bean。

使用message-driven bean(mdb)作为facade,通过增加异步,容错方式执行用例的能力,增强了session facade模式。当我们使用message facade,一个应用程序的每个用例中的商业逻辑映射到它自己的mdb。

考虑先前的例子。我们的在一次航班上预定一个座位的商业逻辑现在将在ReserveSeat mdb的OnMessage()方法中被替换。这个mdb的目的是去封装所有和在一次航班上预定一个座位有关的商业和工作流逻辑,并且去异步执行,如图1.6所示。

这里我们有一个servlet客户端创建一个Java Message Service(jms)消息并且传进需要的参数。这个servlet构造一个容纳所有需要的参数(用户的primary key, 航班号,航线primary key)的消息并且发送这个消息到一个被创建做预定座位用例的JMS 目标。通过在合适的目标接受消息,客户端可以自由的继续(显示下一个web页)。在这一点上,mdb容器将试图传送消息到下一个可用的ReserveSeat mdb。如果所有的在池中的Reserve-Seat mdb在消息接受时正在被使用,JMS服务器应该等待直到下一个变成可用的。用session facade执行这个用例,一个完全使用的session bean池将只有一个失败的点,并且客户端将只有手工重试。

当一个mdb变成可用的,容器将执行OnMessage()方法。在这一点上,ReserveSeat mdb将线性的通过执行用例的过程:注册用户到航线,检查是否座位可用,并且定一个座位。当消耗大量时间的过程发生,最终用户可以自由的在站点上冲浪并且去做他(或她)自己的事。

message facade比session facade的一个重要优势是异步执行用例能得到保证。那就是,如果事务在任何点失败了(可能航线系统当掉了或其它系统失败发生了),事物将会回滚并且JMS消息将会被放回到队列中。事务将会晚些时候重试,无需客户端的知识。

这个幕后行为同样也展现了一个问题。如果用例失败了或成功了,客户端怎样知道呢?举个例子,如果一个座位不能被预定因为飞机被全部预定满了,客户端需要知道。在一个同步模型中(使用session facade),客户端将会立即知道。在一个异步模型中,客户端不再等待得知用例是否成功,并且需要被用特定应用的FORM来提醒。最通常的解决方案是email。如果用例成功或失败了那么系统将用email通知用户。有些公司可能实现一个系统用如下的方式:用人来打个电话,等等。如果应用需求允许,有些应用能采用"拉"的模型。那就是,最终用户将被分配一个特定的他们能去检查他们的请求的状态的位置,和被现代导游服务采用的轨迹号(tracking number)相似。

这里的结论是当使用message facade模式,开发者必须设计新的方式去传递用例的结果到客户端。

使用message facade模式的一个缺点是现在商业逻辑是同时分布到mdb(为message facade)和session bean(为session facade)。这可能是大家最关心的,不过在一个应用中保持商业逻辑到一个位置会更好一些。一个解决这个问题的聪明的做法是在session facade中实现所有的用例,并且用message facade代理session facade。这种方法,所有使用一个异步的,容错的结构如mdb的好处都被保留了,并同时保持逻辑只局限于在session bean层。

message facade模式的优势包括所有的在session facade模式中所列出的优点,并加上如下优点:
1.立即反映时间/异步通信。当一个客户端传送一个JMS消息,它将自由的继续处理无需等待服务器完成用例并反映。一个较长,复杂的用例因此能被启动而控制流立即返回到用户。

2.消除失败的单独的点。使用messaging将保证你的应用继续工作即使EJB服务器或其他它所依赖的子系统当掉了。举个例子,如果数据库当掉了,mdb事务将不会完成,ReserveSeat消息将保留在队列中并被晚些时候重试。如果EJB容器当掉了,消息也将被储存。如果我们使用同步模型这样的容错能力将不可能。当然,如果你的JMS服务器没有被集群并且当掉了,同样代表一个单独的失败的点,不过至少潜在危险的数目减少了。

然而,作为一个使用mdb的副产品,message facade也有如下的缺点:
1.mdb有弱类型(动态)的输入参数。mdb的角色是消耗JMS消息,这些消息在编译时看上去一样。这和session/entity bean不一样,它们提高了java的内建强类型方法和remote和local interface的参数去在编译时捕获通常的错误。开发者需要额外的注意来用目的mdb所需的合适的内容来load一个JMS消息。一个对这个问题的解决方案是去封装所有来自JMS的数据到一个自定义的数据传输对象,并序列化这个对象到一个JMS消息。

2.mdb没有任何返回值。既然mdb调用是异步的,message facade不能用作需要在执行完后返回值的用例。使用message facade因此表面上和使用session facade相似,在session facade中所有的session bean方法简单的只返回void。然而,使用JMS作为传输机制去从mdb回到消息创建者得到一个反应是可能的,请参照书"Mastering Enterprise java beans,second edition",看看关于这种机制的讨论。

3.mdb不传播异常到客户端。不像session/entity bean, mdb不能从任何它们的方法中抛出应用异常或RemoteException。mdb必须因此处理所有在一些特定应用格式中展现的异常。(就是说,如果出现问题就给用户发邮件,记录错误到一个管理日志中,等等)。

message facade是一个非常强大的建立去耦,高伸缩性的应用的模式。一个典型的EJB系统将可能使用session facade和message facade的结合。session facade是一个清楚的为"读"类型操作的选择,这里客户端需要从服务器的一些数据,或当客户端需要显式的等待用例完成。message facade是一个清楚的更新操作的选择,在这里客户端无需立即看到更新的结果。

message facade对session facade的伸缩性和容错性的优势很明显。论及性能,一个基于消息的系统将比集群的session bean方法更有伸缩性,因为mdb"拉";操作而不是把操作"推"到它们。"拉";方法当我们把它们集群时伸缩得更好,因为用了对系统资源的优化。

开发者应该在他们的设计中仔细评估每个用例,问他们自己那个用例是一个同步的还是异步的。这将是选择一个模式还是另一个模式的决定性因素。




话题树型展开
人气 标题 作者 字数 发贴时间
14560 EJB设计模式之message facade Pcman 7549 2002-07-24 14:45
11564 回复: EJB设计模式之message facade M? 31 2002-08-13 17:25

flat modethreaded modego to previous topicgo to next topicgo to back
  已读帖子
  新的帖子
  被删除的帖子
Jump to the top of page

   Powered by Jute Powerful Forum® Version Jute 1.5.6 Ent
Copyright © 2002-2021 Cjsdn Team. All Righits Reserved. 闽ICP备05005120号-1
客服电话 18559299278    客服信箱 714923@qq.com    客服QQ 714923