[转载]Java 理论与实践: 应该在下一个企业应用程序中使用 JMS 吗?

Java 理论与实践: 应该在下一个企业应用程序中使用 JMS 吗?


消息排队(MQ)工具没有数据库工具(例如关系(SQL)数据库)为人所知或为人理解,数据库工具是几乎所有企业应用程序和大量比较简单的应用程序 中的关键组件。开发人员总是可以采用多种类型的数据产品,其范围包括从廉价的、只能在台式机上使用的数据库(例如 dBase 或 Microsoft Access),到工作组数据库服务器(例如 Sybase SQL/Anywhere),再到企业数据库服务器(例如 DB2 或 Oracle)。 无论您的项目是什么样子的,总有一个价格、性能及功能都适合的数据库产品可供您使用。

和数据库相似,MQ 产品有时被称为面向消息的中间件(MOM),已经出现相当一段时间了。然而,直到最近,MQ 服务器还一直是昂贵的、只能被资金最充足的企业开发人员所用的高端产品。结果,只有非常少的开发人员可以享受在其应用程序中使用消息传递所带来的好处。

大众化的消息排队

幸 运的是,这一状况正在开始改变;现在市场上已经出现了几种价格较低的 MQ 服务器。1997 年,Microsoft 发布了 MSMQ,它是一个事务性消息排队产品,作为 Windows NT Server 中的集成部分 ― 无需额外的许可费用。Sun 将 JMS API 包括在最初的 J2EE 规范中,这极大地促进了消息传递的大众化。在 J2EE 规范的版本 1.3 中,所有的 J2EE 容器都要求包含 JMS 提供程序(provider)。

JMS,也就是 Java 消息服务,它是一种允许 Java 应用程序通过标准化的接口访问范围广泛的 MQ 服务器(或者,按照 JMS 的说法,是提供程序)的 API,就象 JDBC 允许程序通过一个公共接口访问许多不同的数据库服务器一样。大多数 J2EE 容器包含 JMS 提供程序;将来,所有 J2EE 容器都将包含 JMS 提供程序。没有 J2EE 容器也可以使用 JMS;市场上有几种独立的 JMS 提供程序实现。此外,EJB 2.0 规范引入了一种新的 EJB 类型 ― 消息驱动 bean ― 它使得创建利用实体和会话 bean 的消息驱动的组件非常容易。

既然我们都可以使用 JMS 服务,我们就应该学会在应用程序中使用消息传递的能力。Willy Farrell 是 IBM 的一名电子商务设计师,他写了一本优秀的关于使用 JMS 的介绍性教程(参阅 参考资料)。 它涉及创建消息和队列的基本知识,以及对消息划分优先级、检索消息和编码消息的所有选项。

消息传递和数据库起了相互补充的作用,在许多情况下,同时使用消息传递和关系数据库可以产生比只使用它们中的一个好得多的解决方案。

历 史上,曾经将 MQ 服务器用于面向事件的应用程序(例如财务服务应用程序)或者作为一种与完全不同的系统进行相互操作的方式(例如连接完全不同的数据库应用程序或将一个企业 同另一个在供应链网络中的企业相连接)。术语“面向消息的中间件”经常应用于 MQ 服务器,它强调 MQ 技术主要用途是连接完全不同的系统。然而,随着 MQ 产品成本的降低,许多其它应用程序现在也可以从消息排队中获益。


blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


MQ 服务器做什么?

用 MQ 的说法,消息只是一个字节流(这个字节流可以是一个 XML 文档、一个序列化的 Java 对象、一个文本字符串或甚至是一条空消息)。对消息的解释留给应用程序域来做;MQ 基础结构不对消息施加任何语义和结构限制。消息存储在队列里,MQ 服务器允许您将消息加入到队列以及从队列中取走消息。

到目前为止,消息队列听起来很象简单的链表。从其最简单形式来说,的确是这样的,但是企业 MQ 服务器通过将一些功能特性封装进这一链表管理而增强了其功能:

  • 控制谁可以向队列中写以及谁可以从队列中读的安全性
  • 网络接口,它允许消息生产者和消费者位于不同的地方
  • 事务性支持,这样入队和出队操作都具有事务特性:原子性、一致性、隔离性以及可持久性
  • 分布式事务支持,这样队列操作可以同其它资源管理器(如 SQL 数据库)一起参加分布式事务
  • 持久存储性
  • 负载均衡
  • 故障转移
  • 管理

blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


MQ 的长处

MQ 的长处源自消息处理的异步性质所带来的固有的 松散耦合。 一个实体向队列发布消息与另一个实体除去并处理消息的过程是完全分离的。这两个实体无须同时运行,也无须位于同一系统上,甚至无须知道另一个实体的标识; 它们仅按照自己的时间表同队列交互。它们只须就彼此将接收的消息的格式达成一致;此外,它们无须知道对方的任何其它事情。

松散耦合有许多优点。它提供了一个自然的机制,将一个工作单元分成更小的、独立的组件,这种机 制在处理请求的各阶段之间隐式地创建了抽象。这种细分允许我们方便地一个接一个地抽象每个组件的实现,更好地衡量和管理每个组件对资源的利用,或者使用提 供具有类似功能的组件替换一个组件而无需改变其它组件。

JMS 规范要求 JMS 提供程序也实现 发布和订阅功能,该功能允许您创建不同的、应用程序定义的且名称为 主题的 通道,并允许单个实体订阅这些主题。排队到主题的消息自动放置在任何订阅过该主题的实体的专用队列中。主题在财务服务或新闻发送应用程序中执行有价值的排 序功能。例如,虽然有 5000 多种股票在美国的主要交易所交易,但每个投资者可能只对其中的 30 种股票感兴趣。因此您可以为每个订单符号创建一个主题,让用户订阅他们感兴趣的符号,然后让 MQ 引擎执行仅仅显示每个投资者想要的报价,避免发送重复的股价。用 SQL 数据库实现这一过程要困难得多。


blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


经典的 MQ 用法模式

有一些最适合于使用消息排队的常见用法模式。当在您的应用程序中看到这些模式之一时,您应该考虑使用消息传递。

面向事件的应用程序

高 度面向事件的应用非常适于使用 MQ 技术。这些包括财务服务应用程序(请考虑一个证券交易所,它显示股票价格更新,根据价格变化或其它订单的执行来启动交易,报告订单状态等等),新闻发送服 务应用程序以及供应链应用程序。在金融市场中,必须对事件进行迅速处理;当发生了重要的事情时,您希望在它一发生时就得到通知。

轮询数据库

数据库在持久存储数据方面是非常优秀的,但是存储瞬时数据并在数据改变时通知我们却不是它们的长处。

虽 然它不是高效的,但是轮询数据库却非常常见。每个机场的显示监视器不断轮询数据库以更新它们显示的信息。有许多出纳窗口的银行经常使用电子信号来指示下一 个空闲出纳员的位置。电子商务站点内的订单处理系统可能轮询数据库以查看是否有任何新订单需要处理。或者保险索赔工作流系统可能轮询以查看是否有任何新的 索赔可以分配给空闲的索赔调解人(claims adjusters)。

所有这些轮询都产生了许多额外的工作。 如果有许多实体频繁地轮询(并且如果它们想要迅速地反映数据的更新,它们就必须这么做),就可能给数据库服务器和网络造成很大的负载。在大多数时候,轮询 不返回数据,更糟的是,会返回我们已经见过的数据,但又必须再次处理或标识为已经处理过。

数据库不只是为轮询或事件而设计的。如果在事件发生或数据更改之后必须采取相对迅速的行动,那么异步消息传递是完成这一任务更容易和更有效的方法。无论何时在需要知道更新而轮询数据库时,请考虑使用 JMS 来替代数据库。

工作流

根 据工作流门户网站(它是 Workflow Management Coalition 和 Workflow And Reengineering International Association 共同努力的结果)的定义,工作流是“……整个或部分商业过程的自动化,在这一过程中,根据一套过程规则,将文档、信息或任务从一个参与者传递给另一个参与 者。”MQ 解决方案特别适合于工作流应用程序(例如文档路由和批准、保险索赔处理等等),这是因为 MQ 技术对如何处理大量使用纸张的办公室里的工作流问题进行了精细的建模,在这种办公室内每个参与者都有一个收件箱和发件箱。

工 作流应用程序的特征是有许多代理(代理可以是人,自动处理步骤甚至是物理装备,例如机器和打印机),每个代理都执行任务的一小部分并将其传递给由业务规则 所确定的下一代理。请考虑批准和支付电子支出报表这一过程。雇员创建并提交报表,接下来该报表需要由雇员的经理批准(如果美元数目超出了规定的数目,则需 要由另外一级管理部门批准)。接下来到了人力资源部,在那里对它进行核查以确定其准确性,还要进行细查以确保该开支是有效的业务支出并符合公司的政策。如 果批准了,将会创建支付请求并安排打印支票。这之后,可能进入财务部,在那里单个收费记录将会应用到适当的帐户和成本中心。在这些阶段的每一个,支出报表 都可能被弹回给雇员或雇员经理。

在构建工作流应用程序过程中,主要设计目标是确保工作能够从一个代理迅速地传入到另一个代理,并确保任务不崩溃。MQ 服务器同数据库一起携手工作,它使得向您的应用程序中构建灵活、可伸缩、可扩展的工作流处理变得容易。


blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


使用 MQ 以从关键路径去除风险大的操作

在电子商务或供应链应用程序中的接收、批准和填写订单同工作流应用程序有许多共同之处,虽然大多数步骤涉及的是电子参与者而不是人。接收并履行订单可能会包含下列步骤中的一些或全部:

  • 接收订单并将其存储在数据库中。
  • 对于消费者顾客,验证信用卡。
  • 对于商业顾客,通过信用报告代理处或通过您公司的信用部门检查该顾客的信用。
  • 执行一些欺诈核查分析。
  • 核查库存。
  • 在有多个履行中心的情况下,决定由哪个中心填写该订单。
  • 向顾客发送一封确认电子邮件。
  • 向顾客的销售代表发送一个通知。
  • 生成挑选列表并将其交付给履行中心。
  • 交付订单。
  • 向用户收费并给其开票据。

由 于您不想顾客在为获取确认号码和收据而单击“Buy”之后等很久,因此无论在提交之后执行哪一条代码,该代码路径都应该简短并且有可预见的执行时间。但是 这些步骤中的许多步骤都需要访问一些资源,这些资源在客户下订单时可能可用也可能不可用,或者这些资源的响应时间可能无法预料。在这种情况下,应该从关键 路径去除它们;让订购的启动动态设置事件链,而通过将提交步骤的工作减到绝对最小来开始订单,来尽可能快地使用户脱离循环。除了将给顾客一个更好的用户经 历之外,将订单处理分成多个离散的(较短)的步骤还改进了资源利用并减少了竞争 ― 这意味着事务更短(因此锁定也释放得更早),并且在一步(例如网络和数据库连接)中所用到的资源也释放得更早。

在 订单处理过程中,最不可预见的步骤之一是发送确认电子邮件。邮件服务器经常会拥塞,可能会要好长时间才能接收一条消息,也可能完全拒绝连接。如果顾客的邮 件服务器拒绝确认消息,那么您就想要稍后重新尝试发送该消息。这样,发送确认电子邮件就“有风险”,这是因为第一次发送可能不成功,或者发送需要很长时间 来处理,而您又不想让顾客(或有关这件事的任何其它的东西)一直等到确认到来。类似地,库存可能存储在同订单处理分离的数据库中(库存数据库可能由一个外 包的履行服务拥有),并且在订购时可能不可用。或者信用部门可能在星期五不上班。

通过使用消息队列来存储暂挂的确认电子邮件、库存检查或者信用检查,您可以将“有风险的”操作同过程的其余部分分离,因此也使过程的其余部分避免了操作失败或花费很长时间的风险。由于每个处理步骤只完成一项简单的任务,因而也将极大简化了每个任务的错误处理。


blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


结束语

如 果应用得当,消息排队技术通过将任务分解成子任务,可以极大地简化复杂任务的处理,还能增加应用程序的灵活性和可伸缩性。自 J2EE 版本 1.3 起,每个 J2EE 容器都将包含一个 JMS 提供程序,这意味着我们都能在我们的应用程序中利用异步消息排队的强大功能。

下 个月,我们将探索 Java 事务服务(Java Transaction Service (JTS))的工作原理了。虽然它不如 EJB 或 J2EE 的其它元素引人注意,但 JTS 可能是 J2EE 的最关键部分 ― 事务使我们能够构建可靠的分布式应用程序。我们将在今后的某篇专栏文章中重述 MQ,并且构建一个工作流应用程序,以演示消息排队和关系型数据库是如何相互协作和取长补短的。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/374079/viewspace-130115/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/374079/viewspace-130115/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值