Sun Java logo     上一页      目录      索引      下一页     

Sun logo
Sun Java System Message Queue 3 2005Q1 技术概述 

第 3 章
可靠消息传送

本章介绍 Message Queue 服务如何提供可靠的消息传送。它描述了消息在系统内的传送路径,并介绍用来将消息路由和传送到相应消费者及确保消息得到传送的各种机制。

本章涵盖以下主题:

开发者和管理员都会对本章的内容感兴趣,它是对第 2 章“Message Queue 简介”中信息的补充。


消息在系统中的传送路线

图 3-1 中简要说明了 Message Queue 消息服务将消息从消息生产者传送到消息消费者的过程。以下各小节对传送过程的每个阶段进行了更详细的说明。

图 3-1 消息传送步骤

图表显示在消息传送过程中,以持久、可靠的方式传送消息的步骤。图表用文本进行说明。

以持久、可靠的方式传送消息的步骤如下:

消息生成

1.   客户机运行时通过连接将消息从消息生产者传送到消息服务器。

消息处理和路由

2.   消息服务器从连接读入消息,然后将其置于相应的目标中。

3.   消息服务器将(持久性)消息置于数据存储库中。

4.   消息服务器向消息生产者的客户机运行时确认已收到消息。

5.   消息服务器确定消息的路由。

6.   消息服务器将消息从其目标写出到适当的连接。

消息使用

7.   消息消费者的客户机运行时将消息从连接传送到消息消费者。

8.   消息消费者的客户机运行时向消息服务器确认消息的使用。

消息生命周期结束

9.   消息服务器处理客户机确认,将(持久性)消息从其目标和数据存储库中删除。

10.   消息服务器向消费者的客户机运行时确认,告知客户机确认已得到处理,不能再次传送此消息了。

在这些传送步骤中,系统处理的消息分为以下两类:


消息传送处理

在将消息从生产者传送到消费者的过程中,Message Queue 服务对消息的处理分几个阶段进行,如图 3-1 后面的步骤说明所示。

这些阶段如下:

以下小节中将逐一介绍这些阶段。

消息生成

在消息生成过程中,由客户机创建消息,然后由客户机运行时通过连接将消息发送至代理中的目标。

如果已将消息的传送模式设置为持久性(有保证的传送,传送且只传送一次,即便代理发生故障),则默认情况下,代理将控制消息(代理确认)发送回客户机运行时。该代理确认指示代理已将消息传送到其目标,并将其存储在代理的数据存储库中。客户机线程将阻塞,直到它收到代理确认为止。

如果将消息的传送模式设置为非持久性,则默认情况下,代理不会将代理确认发送回客户机运行时,客户机线程不会阻塞。不过,如果了解代理是否收到非持久性消息很重要,则可以启用代理确认。实际上,必须启用代理确认才能使代理在达到目标内存限制时降低消息生成速度(请参见目标消息限制)。

消息处理和路由

代理收到外来的 JMS 有效负荷消息时,会将其置于它的目标中,然后将其路由到相应的一个或多个消费者。

通常,所有消息始终保留在它们的物理目标(内存中)中,直到被传送或过期。如果代理出现故障,这些消息将会丢失。如果消息是持久性的,代理会将其存储在数据库或文件系统中,并在发生故障后对其进行恢复。

消息的处理方式取决于其目标类型,即队列目标或主题目标,以下各节对二者进行了说明。此外,还取决于管理员创建物理目标时为目标设置的属性。

队列目标

队列目标用于点对点消息传送;在这种消息传送方式中,消息只传送给一个消费者且只供该消费者使用。

虽然队列中的任何消息仅传送到单个消费者,但 Message Queue 允许在队列中注册多个消费者。然后,代理可将消息分布至其他注册消费者,由这些消费者平衡负荷。

基本路由机制

当来自生产者的消息到达时,即被加入队列。当每条消息到达队列前端时,就会将其路由到已在队列中注册的某个消费者。消息到达队列前端的顺序取决于它们进入队列的顺序及其优先级。

如果在消息中设置了选择器属性值,则代理会将该值与已注册的消费者所指定的任何选择器值进行比较,确保两者匹配,然后再将消息路由到消费者。

多个消费者的队列传送

对多个消费者的队列传送的实现是根据多个队列目标属性使用可配置的负荷平衡方法:

如果消费者数量超过这两个属性的和,将拒绝新的消费者。(Message Queue Platform Edition 支持每个队列多达 3 个消费者(2 个活动和 1 个备份),而 Message Queue Enterprise Edition 支持无限个消费者。)

负荷平衡机制考虑了不同消费者的消息使用率。队列目标中的消息按可配置大小的批次(队列目标的消费者流限制属性)路由至新的可用活动消费者(以便在队列中注册)。在传送这些消息后,到达队列的其他消息将在消费者可用时按批次路由至消费者。当消费者所使用的消息数已达到先前传送给它的消息的某个百分比(可以对其进行配置)时,该消费者即变为可用。换句话说,每个消费者的发送率取决于消费者的当前容量和消息处理速率。

如果某个活动消费者失败,则第一个备份消费者变为活动消费者,并接管失败消费者的工作。由于这些机制,当队列目标中有多于一个的活动消费者时,消息使用的顺序是不一定的。

当消息生成速率较低时,代理可在活动消费者之间不平衡地发送消息。如果活动消费者多于所需个数,其中的一些可能永远收不到消息。

在代理群集环境中,对多个消费者的传送可设置为优先考虑本地消费者。可以使用队列目标属性,指定仅当生产者的主代理(即,生产者将消息发送到的代理,本地代理)中无消费者时,才能将消息传送到远程消费者。这可在路由到远程消费者(通过主代理)可能导致流通量降低时提升性能。

主题目标

主题目标用于发布/订阅消息传送,在该消息传送中,消息将被传送到所有已在目标中注册请求的消费者。

基本路由机制

当来自生产者的消息到达时,它将被路由到所有订阅该主题的消费者。如果消费者已注册了该主题的长期订阅,则当消息到达时,它们不必处于活动状态以接收消息:代理将存储该消息,直到消费者再次变为活动状态为止,然后传送该消息。

如果在消息中设置了选择器属性值,代理会将该值与注册的消费者所指定的任何选择器值进行比较,确保两者匹配,然后再将消息路由到消费者。

长期订阅和客户机标识符

只有一位用户可以建立对某主题的长期订阅。在该用户打开和关闭与消息服务器的连接时,其标识必须保持不变。客户机标识符用于确保每个长期订阅只对应一位用户。

客户机标识符在客户机的连接与消息服务器间建立关联,由消息服务器代表客户机来维护状态信息。按照定义,客户机标识符是唯一的。

要创建长期订阅,客户机标识符必须由客户机使用 JMS API 以编写方式进行设置,或者在客户机使用的连接工厂对象中以管理方式进行配置。

消息使用

路由消息后,即会将其传送给相应的消费者。当消费者收到有效负荷消息时,消费者客户机运行时向代理发送一个确认,说明客户机已收到消息并对消息进行了处理。代理等待该客户机确认,确认后才会将消息从其目标中删除。客户机确认可以应用于个别消息、消息组或事务。

客户机确认

按照 JMS 规范,客户机可以在创建会话时指定三种基本确认模式中的一种。选择哪一种模式取决于所需的消息传送可靠性:

Message Queue 通过增加 NO_ACKNOWLDEGE 模式,扩展了客户机确认模式集。以下小节对这些基本及扩展模式进行了说明。

AUTO_ACKNOWLEDGE 模式

AUTO_ACKNOWLEDGE 模式下,会话自动确认客户机使用的每条消息。此外,会话线程会阻塞,等待代理确认它已处理了每个已使用消息的客户机确认。而该确认称为“代理确认”。

CLIENT_ACKNOWLEDGE 模式

CLIENT_ACKNOWLEDGE 模式授予客户机最高的控制权限。在此模式下,客户机在使用一条或多条消息后显式对其进行确认。确认发生在客户机调用消息对象的 acknowledge() 方法时,会导致会话确认自上次调用该方法以来它使用的所有消息。(其中可能包括会话中许多不同的消息侦听器以异步方式使用的消息,与使用这些消息的顺序无关。)

此外,会话线程会阻塞,等待为已使用的一批消息返回代理确认,它确定代理已对客户机确认进行了处理。

由于通常按批次发送客户机确认和代理确认(而非逐个发送),因此,与 AUTO_ACKNOWLEDGE 模式相比,CLIENT_ACKNOWLEDGE 模式通常节省连接带宽,并减少代理确认的开销。当然,如果在此模式下客户机对每条消息逐一进行确认,则不会按批次发送确认,而是逐一地发送确认。


Message Queue 还提供了一种可以在 CLIENT_ACKNOWLEDGE 模式下使用的特定方法,可以利用该方法,只确认调用了该方法(而非标准行为)的个别消息。这是使用 Message Queue Developer's Guide for Java Clients 中介绍的编程技术实现的。


DUPS_OK_ACKNOWLEDGE 模式

DUPS_OK_ACKNOWLEDGE 模式下,会话在使用了十条消息后进行确认。目前无法对该值进行配置。与 AUTO_ACKNOWLEDGECLIENT_ACKNOWLEDGE 模式不同的是,会话线程不会阻塞等待代理确认,因为在 DUPS_OK_ACKNOWLEDGE 模式下不请求任何代理确认。

这意味着,无法保证只对消息传送和使用一次。一般来说,不会非常频繁地重新传送消息;这种情况只会在发生故障(代理未收到它所传送的消息的客户机确认)时出现。如果客户机对重复传送并不在意,则应使用 DUPS_OK_ACKNOWLEDGE 模式。

由于客户机确认按批次发送且客户机线程不会阻塞,因此消息吞吐量通常远高于其他模式。

NO_ACKNOWLEDGE 模式

NO_ACKNOWLEDGE 模式下,代理会代表客户机进行客户机确认,因此不能保证消费者客户机已成功地对消息进行了处理。

如果消息吞吐量很重要,而传送的可靠性并不是很重要,则请使用此模式。例如,可能会出现以下情况:定期发送消息的时间间隔很短,因而消息负荷很高,此时丢失一些消息不会有太大的影响。

此模式扩展了 JMS 规范,只应由不需要与其他 JMS 提供者配合使用的客户机使用。

事务

上述客户机和代理的确认过程同样适用于编组为事务的 JMS 消息传送。在此类情况下,客户机和代理确认在事务(包括事务中包含的所有消息)级别进行。当提交事务时,将自动发送代理确认。

代理会跟踪事务,使它们可以在出现故障时进行提交或回滚。该事务管理也支持本地事务(较大的分布式事务的一部分,请参见分布式事务)。代理会一直跟踪这些事务的状态,直到它们被提交。当代理启动时,它会检查所有未提交的事务,在默认情况下,回滚未处于 PREPARED 状态的所有事务(必须手动解决)。

Message Queue 通过 XA 连接工厂支持分布式事务。XA 连接工厂使您可以创建 XA 连接,XA 连接又可以使您创建 XA 会话。另外,要支持分布式事务还需第三方 Java 事务服务 (JTS) 或提供 JTS 的 J2EE 兼容应用服务器。

消息生命周期结束

在将消息成功传送后,代理会将其从目标内存中删除。不过,有时在未成功传送消息的情况下,可能会将其放弃。以下小节介绍在哪些条件下会将消息放弃。

正常的消息删除

正常情况下,在成功传送消息(通过客户机确认进行确认)后,代理就会将消息从目标内存中删除。

当代理将消息传送给消费者时,它就会将消息标记为已传送,但它实际上并不知道是否已收到和使用消息。因此,代理等待客户机确认后,再将消息从其物理目标和持久性存储中删除。

如果将消息发送到某个主题,代理从它将消息传送到的每个消息消费者收到客户机确认后,才会将消息删除。对于某个主题的长期订户,代理会将每条消息保留在该目标中,以便在每个长期订户变为活动消费者时将消息传送出去。代理会在收到客户机确认时进行记录,并且只有在收到所有确认后才会删除消息(除非在这之前消息已过期)。根据客户机确认模式的不同,代理可能会通过将代理确认发送回客户机来确认已收到客户机确认。

如果代理或连接发生故障,代理可能会收不到客户机确认,并重新传送所有先前已传送但未得到确认的消息,并为其标记已重新传送标志。 例如,如果队列消费者在确认收到消息之前脱机,随后另一位消费者(或者甚至是同一消费者)在队列中进行了注册,则代理会向该新消费者重新传送未确认的消息,并为其标记已重新传送标志。关注消息在此类情况下重新传送的客户机应用程序应检查消息是否有该标志。


客户机可以通过一种 JMS API (恢复会话),明确请求重新传送客户机已收到但尚未确认的消息。重新传送此类消息时,代理会为它们标记已重新传送标志。


异常的消息删除

消息无法传送时,系统会将其放弃或置于停用消息队列中,具体情况取决于阻止其传送的因素。

在下列情况下,消息在尚未成功传送和使用的情况下将被代理放弃:

不过,在以下情况下,将消息视为停用,并将其放弃或置于停用消息队列中,具体情况取决于所配置的行为:

可以选择保留此类消息,并将其置于停用消息队列中。将消息置于停用消息队列中时,代理会向消息中写入特定于 Message Queue 的属性值,指定放置的时间和原因。

以后,可以从停用消息队列中检索消息以便进行诊断。有关详细信息,请参见停用消息队列


性能问题

消息传送的可靠性越高,需要的开销和带宽就越多。因此,性能和可靠性之间的折衷是设计时要重点考虑的一个方面。您可以选择生成和使用非持久性消息来获得最佳性能。另一方面,您可以通过生成和使用持久性消息并使用事务会话来获得最佳可靠性。在以上两种极端情况之间存在若干种选择,具体情况取决于各应用程序的需要。

例如,消息处理速率受许多因素的影响,其中包括消息传送应用程序设计、消息服务器配置和客户机运行时配置。虽然这些因素差异很大,但它们之间存在的交互可能会增加最大限度提高性能这一任务的复杂性。

本节简要介绍其中的几个因素,它们与可靠性和性能折衷有关。

传送模式     传送模式指定是将消息至多传送一次(非持久性消息)还是传送且只传送一次(持久性消息)。要管理持久性消息,您需要使用通过连接传送的代理确认消息,还需要使用客户机确认模式,它会阻塞以等待接收代理确认。要增加吞吐量,可以将客户机运行时设置为抑制代理确认,但这样做将无法保证持久性消息被传送且只传送一次。

客户机确认模式     四种客户机确认模式需要不同级别的处理和带宽开销。AUTO_ACKNOWLEDGE 模式的开销最大,可以保证消息逐条传送的可靠性;CLIENT_ACKNOWLEDGE 模式按批次发送确认,因此需要的带宽开销较小;而 DUPS_OK_ACKNOWLEDGE 模式的开销最小,但允许重复传送消息。NO_ACKNOWLEDGE 模式可以提供最佳性能,代价是可能会丢失消息。

客户机应用程序设计     在会话中排队等候的消息数是使用该会话的消息消费者数量以及每个消费者的消息负荷的函数。如果客户机生成或使用消息的速度很慢,您通常可以通过下列操作提高性能:重新设计应用程序,以便在更大数量的会话之间分布消息生产者和消费者,或者在更大数量的连接之间分布会话。Message Queue Developer's Guide for Java Clients 和 Message Queue Developer's Guide for C Clients 中介绍了影响性能的设计问题。

消息流测量     客户机运行时可以管理控制消息和有效负荷消息争用连接带宽的问题。通过对客户机运行时进行适当配置,可以帮助提高代理确认的传送速度,从而释放阻塞的会话线程并提高消息的使用速度。有关详细信息,请参见 Message Queue 管理指南。

消息流限制     接近客户机运行时资源极限时,消息使用速度可能会下降。通过限制客户机运行时中保留的消息(等待被一个或多个消费者使用)的数量,可以避免达到这些资源极限。有关详细信息,请参见 Message Queue 管理指南。



上一页      目录      索引      下一页     


文件号码 819-2223。版权所有 2005 Sun Microsystems, Inc.  保留所有权利。