上一章 目录 索引 下一章 |
Sun Java System Message Queue 3.5 SP1 管理指南

> ## 第 1 章
> 概述

> 本章提供了 Sun Java System Message Queue 的入门知识，适合于管理员和程序员阅读。

> ##

> 什么是 Sun Java System Message Queue？

> Message Queue 产品为分布式应用程序进行可靠的异步消息传送提供了基于标准的解决方案。Message Queue 也是实现了 Java Message Service (JMS) 开放标准的企业消息传送系统：事实上它是 JMS 参考实现方案。然而，Message Queue 也是具有企业强度特点的全功能 JMS 提供者。

> JMS 规范用于说明一套消息传送语义和行为，以及应用编程接口 (API)，它们为 Java 语言应用程序提供了在分布式环境中创建、发送、接收和读取消息的通用方法（请参见“JMS 编程模型”）。除了支持 Java 消息传送应用程序外，Message Queue 还提供了 Message Queue 服务的 C 语言接口 ( Message Queue C-API)。

> 使用 Sun Java System Message Queue 软件，在不同平台和操作系统上运行的进程可以连接到一个通用的 Message Queue 消息服务（请参见“消息服务体系结构”），以发送和接收信息。这样，应用程序开发者就可以将精力集中在应用程序的业务逻辑上，而不是集中在应用程序如何在网络中进行可靠的通信这样的细枝末节上。

> Message Queue 具有超出 JMS 规范最低要求的功能，包括：

> 集中式管理。 提供命令行和 GUI 两种工具来管理 Message Queue 服务并管理应用程序相关实体，如目标、事务、长期订阅和安全性。Message Queue 还支持对 Message Queue 服务进行远程监视。

> 可伸缩的消息服务。 您可以在以串连模式（多代理群集）工作的大量 Message Queue 消息服务器组件（代理）之间平衡负荷，从而为不断增加的 Message Queue 客户机（组件或应用程序）提供服务。

> 客户机连接故障转移。 自动恢复已经与 Message Queue 消息服务器断开的客户机连接。

> 可调整的性能。 在可以降低传送可靠性的情况下，提高 Message Queue 服务的性能。

> 多种传输协议。 支持 Message Queue 客户机使用多种不同传输协议（包括 TCP 和 HTTP）与 Message Queue 消息服务器进行通信的功能，并支持使用安全 (SSL) 连接。

> JNDI 支持。 支持将 Java 命名和目录接口 (JNDI) 的基于文件的实现方案和 LDAP 实现方案用作对象存储和用户信息库。

> SOAP 消息传送支持。 支持通过 JMS 消息传送来创建和传送 SOAP 消息（即符合简单对象访问协议 (SOAP) 规范的消息）。SOAP 允许在分布式环境中的点之间交换结构化 XML 数据。有关详细信息，请参见《Message Queue Java Client Developer's Guide 》。

> 有关相关 JMS 兼容问题的文档，请参见附录 G“Message Queue实现方案可选的 JMS 功能”。

> ##

> 产品版本

> Sun Java System 可在两个版本中找到 Message Queue：平台版和企业版，每个版本对应于不同的功能集和许可功能，如下所述。（有关对 Message Queue 进行版本升级的说明，请参见《Message Queue 安装指南》。）

> ### 平台版

> 此版本可以从 Sun 的 Web 站点免费下载，并且还附带有 Sun Java System Application Server 平台。平台版对 Message Queue 消息服务器所支持的客户机连接的数量没有限制。它附带两个许可证，如下所述：

> - 基本许可证。此许可证提供基本的 JMS 支持（它是 JMS 的全权提供者），但是不具有某些企业功能，如负荷平衡（多代理消息服务）、HTTP/HTTPS 连接、安全连接服务、可伸缩连接功能、客户机连接故障转移、多使用方队列传送、基于消息远程监视以及 C-API 支持。此许可证没有期限限制，因此可用于要求不太严格的生产环境。
> - 90 天试用企业许可证。此许可证具有基本许可证所没有的全部企业功能，如支持多代理消息服务、HTTP/HTTPS 连接、安全连接服务、可伸缩连接功能、客户机连接故障转移、多使用方队列传送、基于消息远程监视以及 C-API 支持。但是，软件许可证的期限限制为 90 天，因此，此许可证适用于评估本产品企业版所提供的企业功能（请参见“企业版”）。

> 注意 | 可通过启动 Message Queue 消息服务器（一个 Message Queue 代理实例）来启用 90 天试用许可证，如“启动具有企业版试用许可证的代理实例”中所述。

> ### 企业版

> 此版本用于在生产环境中部署和运行消息传送应用程序。它支持多代理消息服务、HTTP/HTTPS 连接、安全连接服务、可伸缩连接功能、客户机连接故障转移、多使用方队列传送、基于消息远程监视和 C-API 支持。您还可以使用企业版进行开发、调试，并可以装入测试消息传送应用程序和组件。企业版对许可证没有期限限制，对多代理消息服务中的代理数量也没有限制，但对使用的 CPU 数量有限制。

> ##

> 企业消息传送系统

> 企业消息传送系统使独立的分布式应用程序或应用程序组件可以通过消息进行交互。这些组件（无论是在相同的主机、相同的网络上运行，还是通过 Internet 松散地连接在一起）均使用消息传送来传递数据以协调各自的功能。

> ### 企业消息传送系统的要求

> 企业应用程序系统一般都包括大量的分布式组件，这些组件在全天候的关键任务操作中交换数以万计的消息。要支持这样的系统，一个企业消息传送系统一般必须满足以下要求：

> 可靠的传送。 从一个组件向另一个组件传送的消息不能由于网络或系统故障而丢失。这就意味着系统必须能够保证成功地传送消息。

> 异步传送。 为了使大量组件能够同时交换消息，并支持高密度吞吐量，消息的发送就不能取决于使用方是否可以立即接收消息。如果某个使用方正忙或处于脱机状态，系统必须允许进行这样的操作：先将消息发送出去，然后当该使用方准备就绪时再接收消息。这就是所说的异步消息传送，也常称为存储并转发消息传送。

> 安全性。 消息传送系统必须支持基本的安全功能：用户验证、消息及资源的访问授权和摘要式加密。

> 可伸缩性。 消息传送系统必须能够在不降低系统性能或消息吞吐量的前提下容纳不断增长的负荷，即用户数量和消息数量的增加。当业务和应用程序扩展时，这将成为一个十分重要的要求。

> 易管理性。 消息传送系统必须提供用于监视和管理消息传送以及优化系统资源的工具。这些工具有助于衡量和维护系统的可靠性、安全性和性能。

> ### 集中式消息传送与点对点消息传送

> 传统的点对点消息传送系统很难满足企业消息传送系统的要求，如图 1-1 所示。

> 图 1-1 集中式消息传送与点对点消息传送

> 在点对点系统中，每一个消息传送组件与所有其他组件都保持连接。这些连接可以实现快速、安全和可靠的传送，但是支持可靠性和安全性的代码必须驻留在每一个组件中。随着组件不断添加到系统中，连接的数量将成指数级增加。这使得异步消息传送和可伸缩性很难实现。集中式管理也变得问题重重。

> 企业消息传送首选的解决方案就是采用集中式消息传送系统，如图 1-1 中所示。在该解决方案中，每个消息传送组件只需与一个中央消息服务保持连接。消息服务提供组件之间的消息路由和传送，并负责可靠传送及安全。组件通过定义完善的程序接口与消息服务进行交互。当系统中添加组件时，连接的数量只会线性增加，这样就可以轻松地通过调整消息服务来调整系统。另外，中央消息服务为系统提供集中式管理。

> ### 消息传送系统概念

> 以下几个基本概念构成了企业消息传送系统的基础，包括：消息、消息服务体系结构和消息传送模型。

> #### 消息

> 消息由采用某种格式的数据（消息主体）和说明消息属性或特征（例如目标、有效期或其他由消息传送系统确定的属性）的元数据（消息标题）构成。

> #### 消息服务体系结构

> 图 1-2 所示为消息传送系统的基本体系结构。它包括消息生成方和消息使用方，它们利用通用消息服务来交换消息。同一消息传送组件（或应用程序）中可以驻留任意数量的消息生成方和消息使用方。消息生成方将消息发送至消息服务。接下来，消息服务使用消息路由和传送组件将消息传送至一个或多个已注册对此消息的请求的消息使用方。消息路由和传送组件负责保证将消息传送至所有相应的使用方。

> 图 1-2 消息服务体系结构

> #### 消息传送模型

> 生成方和使用方之间存在多种关系：一对一、一对多和多对多。例如，您可能会有以下类型的消息：

> - 一个生成方至一个使用方
> - 一个生成方至多个使用方
> - 多个生成方至一个使用方
> - 多个生成方至多个使用方

> 这些关系一般可简化为两个消息传送模型：点对点消息传送和发布/订阅消息传送。点对点传送模型主要处理由一个特定生成方创建并由一个特定使用方接收的消息。发布/订阅传送模型主要处理由任意数量的生成方创建并由任意数量的使用方接收的消息。这两种消息传送模型可以组合起来使用。

> 由于历史原因，消息传送系统支持这两种消息传送模型的各种组合方式。Java 消息服务 (JMS) 规范为 Java 编程创建了利用 API 进行消息传送的标准语义。它既支持点对点消息传送模型，也支持发布/订阅消息传送模型（请参见“编程域”）。

> ##

> JMS 规范

> JMS 规范规定了一套管理消息传送的规则和语义，包括编程模型、消息结构和 API。因为 Message Queue 提供 JMS 的实现方案，所以 JMS 概念是理解 Message Queue 消息传送系统如何工作的基础。本简介说明了理解本书其余各章所需的概念和术语。

> ### JMS 消息结构

> JMS 消息由三部分组成：标题、属性和主体。

> 标题 标题指定了消息的 JMS 属性：目标、是否持久、有效期及优先级。这些属性控制了消息传送系统传送消息的方式。

> 属性 属性（可以看作标题的扩充）为可选项，应用程序可以使用属性提供的值根据各种选择标准来过滤消息。属性为可选项。

> 消息主体 消息主体包括要交换的实际数据。JMS 支持六种主体类型。

> ### JMS 编程模型

> 在 JMS 编程模型中，JMS 客户机（组件或应用程序）通过 JMS 消息服务交换消息。消息生成方将消息发送至消息服务，消息使用方则从消息服务接收这些消息。这些消息传送操作是使用一组实现 JMS 应用编程接口 (API) 的对象（由 JMS 提供者提供）来执行的。

> 本节将介绍实现 JMS API 的对象和用于设置进行消息传送的 JMS 客户机的对象。有关详细信息，请参见《Message Queue Java Client Developer's Guide》。图 1-3 所示为用于编写消息传送的 JMS 对象。

> 图 1-3 JMS 编程对象

> [D]

> 在 JMS 编程模型中，JMS 客户机使用 ConnectionFactory 对象创建一个连接，向消息服务发送消息以及从消息服务接收消息均是通过此连接来进行。Connection 是客户机与消息服务的活动连接。创建连接时，将分配通信资源以及验证客户机。这是一个相当重要的对象，大多数客户机均使用一个连接来进行所有的消息传送。

> 连接用于创建会话。Session 是一个用于生成和使用消息的单线程上下文。它用于创建发送和接收消息的生成方和使用方，并为所发送的消息定义发送顺序。会话通过大量确认选项或通过事务来支持可靠传送。

> 客户机使用 MessageProducer 向指定的物理目标（在 API 中表示为目标身份对象）发送消息。消息生成方可指定一个默认传送模式（持久性消息与非持久性消息）、优先级和有效期值，以控制生成方向物理目标发送的所有消息。

> 同样，客户机使用 MessageConsumer 对象从指定的物理目标（在 API 中表示为目标对象）接收消息。消息使用方可使用消息选择器，借助它，消息服务可以只向消息使用方发送与选择标准匹配的那些消息。

> 消息使用方可以支持同步或异步消息接收。异步使用可通过向使用方注册 MessageListener 来实现。当会话线程调用 MessageListener 对象的 onMessage() 方法时，客户机将使用消息。

> ### JMS 受管理对象

> JMS 规范通过指定封装有提供者特有配置信息的受管理对象，使得独立于提供者的客户机更易于访问这些对象。

> 在“JMS 编程模型”介绍的对象中，有两个对象取决于 JMS 提供者如何实现 JMS 消息服务。连接工厂对象取决于提供者传送消息时使用的基本协议和机制，而目标对象则取决于提供者使用的特有命名惯例和物理目标容量。

> 通常，这些提供者特有属性使得 JMS 客户机代码取决于特定的 JMS 实现方案。不过，JMS 规范要求将提供者特有的实现方案和配置信息封装在连接工厂和目标对象中，可以通过非提供者特有的标准方式对这些对象进行访问。

> 受管理对象由管理员创建和配置，并存储在命名服务中，由客户机通过标准Java 命名和目录服务(JNDI) 查找代码来进行访问。以这种方式使用受管理对象可使客户机代码与提供者无关。

> 两种类型的受管理对象（即连接工厂和目标对象）都可以封装提供者特有的信息，但它们在客户机中的使用情况明显不同。连接工厂用于创建与消息服务器的连接，而目标对象用于标识物理目标。

> ##

> JMS/J2EE 编程：消息驱动 Bean

> 除在“JMS 编程模型”中介绍的通用 JMS 客户机编程模型外，还有专门在 Java 2 Platform Enterprise Edition（J2EE 平台）应用程序上下文中使用的 JMS。这些专用的 JMS 客户机称为消息驱动 Bean，是 EJB 2.0 规范 (http://java.sun.com/products/ejb/docs.html) 中指定的企业 JavaBean (EJB) 系列组件之一。

> 之所以需要消息驱动 bean，是因为其他 EJB 组件（会话 bean 和实体 bean）只能被同步调用。这些 EJB 组件只能通过标准 EJB 接口来访问，因此不具备异步接收消息的机制。

> 但是，异步消息传送是许多企业应用程序的一项必不可少的要求。这些应用程序大多需要服务器端组件能够互相通信和响应，而不占用服务器资源。因此就需要有这样一种 EJB 组件：不需要紧密耦合到消息生成方即可接收和使用消息。对于服务器端组件必须响应应用程序事件的任何应用程序，均必须具有上述功能。在企业应用程序中，此功能还必须在负荷增加时具有可伸缩性。

> ### 消息驱动 Bean

> 消息驱动 bean (MDB) 是由专用的 EJB 容器（为所支持的组件提供分布式服务的软件环境）支持的专用 EJB 组件。

> 消息驱动 Bean MDB 是实现 JMS MessageListener 接口的 JMS 消息使用方。当 MDB 容器接收消息时，onMessage 方法（由 MDB 开发者编写）将被调用。onMessage() 方法使用消息的方式与标准 MessageListener 对象的 onMessage() 方法使用消息的方式一样。不能以调用其他 EJB 组件的方法来远程调用 MDB 的方法，因此不存在与之关联的主接口或远程接口。MDB 可使用来自单一目标的消息。如图 1-4 所示，独立 JMS 应用程序、JMS 组件、EJB 组件或 Web 组件均可生成消息。

> 图 1-4 与 MDB 进行消息传送

> MDB 容器 MDB 由专用 EJB 容器支持，负责创建并设置 MDB 实例，以进行消息的异步使用。这包括建立与消息服务的连接（包括验证）、创建与给定目标关联的会话池、管理在会话池和关联 MDB 实例之间接收到的消息的分发。由于容器控制了 MDB 实例的有效期，因此它通过管理 MDB 实例池来容纳外来的消息负荷。

> 与 MDB 关联的是一个部署描述符，它指定了容器设置消息使用时使用的受管理对象的 JNDI 查找名称：连接工厂和目标。部署描述符还可能包括可由部署工具用于配置容器的其他信息。每个这样的容器只支持一个 MDB 的实例。

> ### J2EE 应用服务器支持

> 在 J2EE 体系结构中（请参见位于 http://java.sun.com/j2ee/download.html#platformspec 的 J2EE 平台规范），EJB 容器由 J2EE 应用服务器托管。应用程序服务器为各种容器提供所需的资源：事务管理器、持久性管理器、命名服务以及 JMS 提供者（对于消息传送和 MDB）。

> 在 Sun Java System Application Server 中，JMS 消息传送资源由 Sun Java System Message Queue 提供：

> - 对于 Sun Java System Application Server 7.0，Message Queue 消息传送系统被作为它的本地 JMS 提供者集成到应用程序服务器中。
> - 对于 Sun J2EE 1.4 Application Server，Message Queue 被作为嵌入式 JMS 资源适配器插入到应用程序服务器中（请参见附录 F“Message Queue 资源适配器”）。
> - 对于应用程序服务器的后续发行版本，将利用标准资源适配器部署和配置方法将 Message Queue 插入到应用程序服务器中。

> ##

> JMS 消息传送相关问题

> 本章介绍了许多影响 Message Queue 消息服务管理的 JMS 编程相关问题，着重介绍 Message Queue 管理员需要的概念和术语。

> ### JMS 提供者无关

> JMS 指定受管理对象的用途（请参见“JMS 受管理对象”）以支持可移植到其他 JMS 提供者的客户机应用程序的开发。受管理对象允许 JMS 客户机使用逻辑名称查找和引用提供者特定的对象。这样，客户机代码无需知道提供者使用的特有命名语法、寻址语法或可配置属性。从而使代码与提供者无关。

> 受管理对象是 Message Queue 系统对象，由 Message Queue 管理员创建并配置。这些对象存放在 JNDI 目录服务中，JMS 客户机使用 JNDI 查找来访问这些对象。

> Message Queue 受管理对象也可以由客户机对其进行实例化，而不是在 JNDI 目录服务中查找。但这样做的缺点是要求应用程序开发者使用提供者特定的 API，并降低了 Message Queue 管理员成功控制和管理 Message Queue 消息服务器的能力。

> 有关受管理对象的详细信息，请参见“Message Queue 受管理对象”。

> ### 编程域

> JMS 支持两种截然不同的消息传送模型：点对点模型和发布/订阅模型。

> 点对点（队列目标） 消息从一个生成方传送至一个使用方。在此传送模型中，目标是一个队列。消息首先被传送至队列目标，然后根据队列传送策略，从该队列（请参见“队列目标”）将消息传送至向此队列进行注册的某一个使用方，一次只传送一条消息。可以向队列目标发送消息的生成方的数量没有限制，但每条消息只能发送至、并由一个使用方成功使用。如果没有已经向队列目标注册的使用方，队列将保留它收到的消息，并在某个使用方向该队列进行注册时将消息传送给该使用方。

> 发布/订阅（主题目标） 消息从一个生成方传送至任意数量的使用方。在此传送模型中，目标是一个主题。消息首先被传送至主题目标，然后传送至所有已订阅此主题的活动使用方。可以向主题目标发送消息的生成方的数量没有限制，并且每个消息可以发送至任意数量的订阅使用方。主题目标也支持长期订阅的概念。长期订阅表示使用方已向主题目标进行注册，但在消息传送时此使用方可以处于非活动状态。当此使用方再次处于活动状态时，它将接收此信息。如果没有已经向主题目标注册的使用方，主题不保留其接收到的消息，除非有非活动使用方注册了长期订阅。

> 这两种消息传送模型使用表示不同编程域的 API 对象（其语义稍有不同）进行处理，如表 1-1 所示。

> 表1-1 JMS 编程对象

> 基本类型（统一域） | 点对点域 | 发布/订阅域
> --- | --- | ---
> Destination（Queue 或 Topic）1 | Queue | Topic
> ConnectionFactory | QueueConnectionFactory | TopicConnectionFactory
> Connection | QueueConnection | TopicConnection
> Session | QueueSession | TopicSession
> MessageProducer | QueueSender | TopicPublisher
> MessageConsumer | QueueReceiver | TopicSubscriber

> 1取决于编程方法，您可以指定特定的目标类型。

> 可以使用表 1-1 第一列中列出的统一域对象编写点对点和发布/订阅消息传送。这是首选方法。然而，为了符合早期的 JMS 1.02b 规范，可以使用点对点域对象编写点对点消息传送，使用发布/订阅域对象编制发布/订阅消息传送。

> ### 客户机标识符

> JMS 提供者必须支持客户机标识符的概念，客户机标识符将 JMS 客户机至消息服务的连接与消息服务代表客户机维护的状态信息关联起来。按照定义，客户标识符是唯一的，并且每次只应用到一个用户。客户机标识符与长期订阅名称（请参见“发布/订阅（主题目标）”）结合使用，确保每个长期订阅只对应一个用户。

> JMS 规范允许客户机通过 API 方法调用来设置客户机标识符，但最好使用连接工厂受管理对象（请参见“JMS 受管理对象”）从管理级别来设置它。但如果硬链接至连接工厂，那么每个用户均需要单独的连接工厂以拥有一个唯一的标识。

> 使用可在 ConnectionFactory 对象中配置的特殊变量替代语法，Message Queue 提供了一个途径，使客户机标识符特定于 ConnectionFactory 和用户。使用此方式时，创建长期订阅的多个用户可以使用一个 ConnectionFactory 对象，而不必担心命名冲突或安全性得不到保障。用户的长期订阅将因此得到保护，不会因另一用户设置了错误的客户机标识符而导致意外删除或不可用。

> 有关如何使用此 Message Queue 功能的详细信息，请参见《Message Queue Java Client Developer's Guide》中连接工厂属性的介绍。

> 无论何时，如果要创建长期订阅，客户机标识符必须由客户机使用 JMS API 在编写程序时设置，或者在客户机使用的 ConnectionFactory 对象中进行管理级别的配置。

> ### 可靠消息传送

> JMS 定义了两种传送模式：

> 持久性消息 保证这些消息只被传送一次和成功使用一次。对于这些消息，可靠性是优先考虑的因素。

> 非持久性消息 保证这些消息最多被传送一次。对于这些消息，可靠性并非主要的考虑因素。

> 对于持久性消息，确保可靠性有两个方面。一个是确保至目标和出自目标的持久性消息传送成功。另一个就是确保在将持久性消息传送至使用方之前，消息服务没有丢失持久性消息。

> #### 确认/事务

> 可靠消息传送的关键在于确保至目标和出自目标的持久性消息传送成功。这可以通过 Message Queue 会话支持的两个通用机制实现：确认或事务。事务（可以是本地事务或分布式事务）是由分布式事务管理器控制。

> ##### 确认

> 可以将会话配置为使用确认来确保可靠传送。

> 对于生成方，这意味着在生成方的 send() 方法返回前，消息服务确认已向其目标发送持久性消息。对于使用方，这意味着在消息服务从该目标删除持久性消息前，客户机确认从该目标发出的持久性消息已传送并已使用。

> ##### 本地事务

> 也可以将会话配置为已处理，这样，可以将一个或多个消息的生成和/或使用组成原子单元，也就是事务。JMS API 提供了启动、提交或回滚事务的方法。

> 在事务中生成或使用消息时，代理跟踪各个发送和接收过程，并在客户机发出提交事务的调用时完成这些操作。如果事务中特定的发送或接收操作失败，则出现异常。客户机代码通过忽略异常、重试操作或回滚整个事务来处理异常。在事务提交时，将完成所有成功的操作。在事务进行回滚时，将取消所有成功的操作。

> 本地事务的范围始终为一个会话。也就是说，可以将单个会话的上下文中执行的一个或多个生成方或使用方操作组成一个本地事务。

> 由于事务的范围只能为单个的会话，因此不存在既包括消息生成又包括消息使用的端对端事务。（换句话说，至目标的消息传送和随后进行的至客户机的消息传送不能放在同一个事务中。）

> ##### 分布式事务

> Message Queue 也支持分布式事务。也就是说，消息的生成和使用可作为较大的分布式事务的一部分，该分布式事务中包括涉及其他资源管理器（如数据库系统）的操作。在分布式事务中，分布式事务管理器使用在 Java 事务 API (JTA)、XA 资源 API 规范中定义的两阶段提交协议跟踪和管理由多个资源管理器（如消息服务和数据库管理器）执行的操作。在 Java 中，JTA 规范说明了资源管理器和分布式事务管理器之间的交互。

> 支持分布式事务是指消息传送客户机可通过 JTA 定义的 XAResource 接口参与分布式事务。此接口定义了实现两阶段提交的许多方法。当客户机端进行 API 调用时，Message Queue 代理只与分布式事务管理器（由 Java 事务服务 (JTS) 提供）协作来跟踪分布式事务中的各种发送和接收操作、事务状态并完成消息传送操作。

> 处理本地事务时，客户机通过忽略异常、重试操作或回滚整个分布式事务来处理异常。

> Message Queue 通过 XA 连接工厂支持分布式事务。XA 连接工厂使您可以创建 XA 连接，XA 连接又可以使您创建 XA 会话（请参见“JMS 编程模型”）。另外，要支持分布式事务还需第三方 JTS 或提供 JTS 的 J2EE 兼容应用服务器。

> #### 持久性存储器

> 可靠性的另一个重要方面是确保持久性消息传送至目标后，消息服务在向使用方传送它们之前不会丢失这些消息。这意味着在持久性消息传送至目标时，消息服务必须将其放入持久性数据存储（请参见“持久性管理器”）。如果消息服务由于某种原因导致失败，它可以恢复此消息并将此消息传送至相应的使用方。虽然这样增加了消息传送的开销，但却增加了可靠性。

> 消息服务还必须存储长期订阅。这是因为要确保主题目标模式下的可靠传送，仅仅恢复持久性消息是不够的。消息服务还必须恢复有关主题的长期订阅的信息，否则它就不能将消息传送至在消息到达时处于非活动状态、随后又恢复活动状态的订阅者。

> 需要可靠消息传送的消息传送应用程序必须将消息指定为持久性消息，并使用队列目标或主题目标的长期订阅。

> ### 性能折衷

> 消息传送的可靠性越高，需要的开销和带宽就越多。性能和可靠性之间的折衷是设计时要重点考虑的一个方面。您可以选择生成和使用非持久性消息来获得最佳性能。另一方面，您可以通过生成和使用持久性消息并使用事务会话来获得最佳可靠性。在这两种极端之间有许多选择，这取决于应用程序的要求，包括使用 Message Queue 特有的连接和确认属性，请参见《Message Queue Java Client Developer's Guide 》。在“影响性能的应用程序设计因素”中对这些折衷进行了更为详细的讨论。

> ### 消息选择

> JMS 提供了一种机制，使用它，消息服务可根据消息选择器中的标准来执行消息过滤和路由。生成方客户机可在消息中放入应用程序特有的属性，而使用方客户机可使用基于这些属性的选择标准来表明对消息是否感兴趣。这就简化了客户机的工作，并避免了向不需要这些消息的使用方传送消息的开销。然而，它也使得处理选择标准的消息服务增加了一些额外开销。在 JMS 规范中对消息选择器语法和语义进行了简要说明。

> ### 消息顺序和优先级

> 通常，可以确保将单个会话向目标发送的所有消息按其发送顺序传送至使用方。然而，如果为这些消息分配了不同的优先级，消息传送系统将首先尝试传送优先级较高的消息。

> 除此之外，客户机应用程序使用消息的顺序只与消息的生成顺序存在一个粗略的关系。这是因为向目标传送消息和从目标传送消息可以取决于多种影响时间的因素，如消息的发送顺序、发送消息的会话（连接）、是否是持久性消息、消息的有效期、消息的优先级、队列目标的消息传送规则（请参见“队列目标”）和消息服务可用性。

> 对于使用多个互连代理（请参见“多代理群集（企业版）”）的 Message Queue 消息服务来说，客户机使用消息的顺序更为复杂，这是因为从不同代理的目标传送消息的顺序是不确定的。因此，一个代理息可能会先于另一个代理传送消息，即使是后者先接收到消息。

> 无论何时，对于一个给定的使用方，优先级较高的消息总是先于优先级较低的消息。

> 上一章 目录 索引 下一章

> 版权所有 2004 Sun Microsystems, Inc. 保留所有权利。