追逐梦想的猪

人生因为有梦想而精彩!

导航

消息队列study------转载

通过使用队列技术提高应用程序的响应速度。

缩短等待时间

一般来说,将应用程序需要处理的工作分为必须立即完成的和可以推迟到稍后完成的。这种做法是很有意义的。

任何不会影响到用户呈递下一页面的东西其处理工作都可以在后台进行。批量更新、汇总计算以及外部处理都很适于在后台进行。

队列是一种能将应用程序的处理工作有效地划分为前台任务和后台任务的技术。当处理容量允许时,这种技术通过存储消息、确定消息处理的优先顺序和向应用程序提交消息来发挥作用。它使你能够平衡本地计算机的负荷,或将任务分配到远程计算机。

为了减少用户的等待时间,应用程序可以让说明需要后台处理的消息排入队列。然后就可以从页面的呈递过程中去掉该处理任务。由一个后台进程来读取并队列处理这些消息,或者甚至可以交由一个单独的系统来处理它们。

Java消息管理系统

J2EE Java消息服务(Java Message Service,JMS)实际上是一个用于访问企业消息管理系统的接口,而不是一个系统。JMS提取了各供应商消息实现方案之间的差别。其想法是使按照JMS API编写而成的应用程序可以在不同的消息产品之间进行移植。

事实上,在可移植性和功能两者之间通常要进行权衡。虽然JMS对应用程序代码(但不是配置)的可移植性提供了一些评测方法,但它对消息系统特性的访问一般极少提供共用标准。

JMS提供了两种编程模型:点到点(point-to-point,p2p)模型和发布与订阅(publish-and -subscribe,pub/sub)模型。JMS规范把它们称为消息传送领域。

在p2p消息传送模型中,将每条消息通过一个队列发送给一个接收者。p2p模型确保一个且只有一个接收者读取每条消息。如果队列中有多个接收者在监听(一个队列比如有一个消息驱动的bean池时),JMS提供者会把每条消息发布给其中的一个接收者。p2p消息模型最适合于事务消息。

在pub/sub消息传送模型中,一个消息生产者可以根据主题把一个消息发送给一个或多个注册的消费(使用)者。消费者可以订阅一个主题。订阅可以是持续的,这使得消费者能够断开与消息的连接,以后再重新连接和检索错过的消息。你可以把pub/sub消息模型看作是一种广播服务--它最适合用于发布者不太关注错过的消息。

由于JMS仅仅是个接口,所以需要对它进行实施,以便完成实际工作。Oracle JMS (OJMS)是高质量的JMS提供者,它基于Oracle的高级队列管理(Advanced Queuing)。

Oracle高级队列管理

高级队列管理是Oracle数据库的一个特性,它提供消息队列管理功能。这是一个非常可靠、安全和可伸缩的消息管理系统,因为它使用与其他基于Oracle技术的应用程序相同的数据库特性。

高级队列管理的一个很大优点是它可以通过PL/SQL、Java或C来访问,这样你就可以把来自一个Java servlet的消息入队列和使PL/SQL存储过程中的相同消息出队列。

高级队列管理的另一个优点是你可以利用这一软件通过Oracle Net Services (SQL*Net)、HTTP(S)和SMTP,在远程节点之间传播消息。高级队列甚至可以通过消息网关与非Oracle的消息管理系统(如IBM MQSeries)相集成。

Oracle高级队列管理提供了单消费者队列和多消费者队列。单消费者队列只面向单一的接收者。多消费者队列可以被多个接收者使用。当把消息放入多消费者队列时,应用程序的程序员必须显式地在消息属性中指定这些接收者,或者建立决定每条消息的接收者的基于规则的订阅过程。

高级队列管理提供的这两类队列与JMS展现的两个消息传送领域相对应。表1概括了两类消息传送样式之间的关系。

消息类型 通常适用场合 基数 JMS域 Oracle高级队列管理的类型
点到点 事务 1对1 队列 单消费者
发布/订阅 广播 1对多 主题 多消费者
表1:消息传送样式的比较

 

要记住的是高级队列管理提供的特性和概念在JMS中是没有的。例如,Oracle高级队列允许消息有多个命名接收者,而JMS没有这样的概念。虽然按照JMS API编写代码一般就足够了,但请记住,你也许还需要编写Oracle的自有Java高级队列API来访问Oracle的所有消息传送功能。

消息驱动Beans

消息驱动beans(MDB,Message-Driven Beans)是一种企业JavaBean(EJB),它使用JMS消息。MDB由J2EE应用服务器管理,它监听消息和维护MDB实例池,自动调用这些实例来接收和处理消息。

MDB比JMS应用程序易于编写,因为应用服务器处理MDB的运行时环境,包括事务、安全性和一致性。这为开发人员提供了一个很大优势,开发人员可以从中解放出来,把精力集中在处理消息的业务逻辑上。当消息到达队列时,自动创建MDB实例来处理这些消息,完成后清除这些实例。

请注意,由于MDB是基于JMS的,因此它们继承了JMS API的局限性;也就是说,你不能访问底层消息管理系统的所有功能。

但是,你一般应在能使用MDB的时候就应该使用,因为应用服务器管理多线程异步消息监听器中所固有的复杂性。对于不能在应用服务器上运行的代码,如单独的客户端应用程序,经实践证明JMS也是有用的(尽管涉及到更大的复杂性)。

一个例子

前面我曾指出任何不影响用户呈递下一页的东西都适用于队列处理。但是,如何进一步提高用户能够察觉到的响应速度,这也许并不总是显而易见的。

为了进行这种改进,可以通过提出这样的问题来改变你考虑工作流的方式:"使用户连续工作而必须做的最少工作是什么?"也许你需要对任务自身的假设提出质疑。

我为一家保险公司完成了一个Web应用程序,该应用程序由公司的电话服务人员用于通过电话处理成员状态的变化。该应用程序必须与两个不同的原有系统相连接,以便更新和验证数据。

假如有一种情况,客户打电话希望把她的地址改为在另一个州的地址。电话服务人员将该信息输入到Web表单并点击Submit(提交)按钮。Web应用程序将该事务转发到两个不同的主机应用程序:一个是健康计划管理应用程序,另一个是退休福利管理应用程序。当健康计划管理应用程序验证该地址变更时,该验证结果表明该客户的当前健康计划在新的州是无效的。

有什么问题吗?所有这些与原有系统的交互操作花费了太长时间。而且还存在可靠性问题:如果有一个主机离线,或者连接的基础设施的任何一部分宕机,则所有电话服务人员都不能接听电话。

此外,管理人员们坚持所有的处理都应在Web应用程序显示下一页之前完成。他们认为Web应用程序必须在用户没有挂断电话前解决事务处理的所有问题。

 

该解决方案就是要向这样一种假设挑战,即所有数据必须在用户能够继续进行下一个任务之前得到验证。在这种情况下,我们发现需要客户额外进行输入的问题极少出现。公司做出了一项设计决定:假设一切运行良好,出现问题时先让客户先挂断电话、然后再给客户打回电话,这样的情况不足1%。

利用HTML框架和少量JavaScript对Web应用程序进行了重新设计,JavaScript可以定期检查服务器,以发现需要注意的问题。

通过重新思考工作流和应用队列技术,该公司已经能够提高系统的可靠性和响应用户及客户请求的速度。

更进一步

关于高级队列管理、OJMS和JMS需要记住下面这些要点:

  • 在建立高级队列管理的队列时,要通过使用OJMS类型(如SYS.AQ$_JMS_ MAP_MESSAGE)之一来说明它是JMS支持的队列。
  • 利用内置的DBMS_AQJMS软件包通过PL/SQL将消息排入JMS队列或从中出列。
  • 不是所有的高级队列管理的特性和属性都能通过标准JMS接口来实现。Java包oracle.jms提供了一些实现公共JMS标准的Oracle扩展的类和接口。

posted on 2006-10-13 17:06  Ann  阅读(868)  评论(0编辑  收藏  举报