![]() | |
Sun Java System Message Queue 3 2005Q1 技术概述 |
第 1 章
基础概念Sun Java System Message Queue (Message Queue) 可以提供可靠的异步消息传送,能够将企业中的分布式应用程序和组件集成在一起。在不同平台和操作系统上运行的进程可以通过连接到该服务来彼此进行交互。
Message Queue 是一种基于标准的消息传送解决方案,它实现了 Java 消息服务 (JMS) 开放标准。此外,Message Queue 还提供了大规模企业部署所需的互操作性、安全性、可伸缩性、可用性、易管理性以及其他功能。
本章介绍 Message Queue 的基础概念。涵盖下列主题:
如果您已熟知 JMS 概念和术语,可以跳过本章,直接阅读第 2 章“Message Queue 简介”。
企业消息传送系统企业消息传送系统使独立的分布式应用程序或应用程序组件可以通过消息进行交互。这些组件无论是在同一主机、同一网络上运行,还是通过 Internet 松散地连接在一起,均使用消息传送来传递数据以协调各自的功能。
为了使大量组件能够同时交换消息,并支持高密度吞吐量,消息的发送就不能取决于消费者是否已做好接收消息的准备。如果某个消费者正忙或处于脱机状态,系统必须允许进行这样的操作:当该消费者准备就绪时再接收消息。这种去耦合的消息发送与接收称为“异步消息传送”。
异步消息传送模型非常适于完成集成复杂系统的任务;对于此类系统,在执行操作的过程中让一个组件为另一个组件提供支持既不切实际,也不值得这样做。尽管异步消息传送放弃了同步系统所具有的某些控制功能,但大大提高了组件间相互作用的灵活性。它还增强了系统的稳定性,因为一个组件的故障并不会导致整个系统瘫痪。
企业消息传送系统的要求
企业应用程序系统一般都包括大量的分布式组件,这些组件在全天候的关键任务操作中交换数以万计的消息。要支持这样的系统,除了支持异步消息传送外,企业消息传送系统还必须满足以下要求:
可靠的传送。 从一个组件向另一个组件传送的消息不能由于网络或系统故障而丢失。这就意味着,系统必须能够保证消息的传送。
安全性。 消息传送系统必须支持基本的安全功能:用户验证、消息及资源的访问授权和线上加密。
可伸缩性。 消息传送系统必须能够在不降低系统性能或消息吞吐量的前提下容纳不断增长的负荷,即用户数量和消息数量的增加。随着业务和应用程序的扩展,这将成为一个很重要的要求。
可用性。 消息传送系统的停机时间必须非常短。也就是说在发生故障时,系统具有足够的冗余以继续提供消息传送服务。
易管理性。 消息传送系统必须提供用于监视和管理消息传送的工具。管理员必须能够优化系统资源以及调节系统性能。
集中式 (MOM) 消息传送
Message Queue 采用集中式消息传送系统,如图 1-1 中所示。在此类系统中,每个消息传送组件只需与一个中央消息服务保持连接。组件通过定义完善的接口与消息服务进行交互。
图中左侧所示为另一种系统,即点对点系统,在该系统中,每个消息传送组件均与所有其他组件保持连接。点对点系统可以实现快速、安全和可靠的传送,但是支持可靠性和安全性的代码必须保存在每一个组件中。消息的发送和接收紧密耦合,因而难以实现异步传送。随着组件被不断添加到系统中,连接的数量将成指数级增加,因此,系统的可伸缩性很差。在点对点系统中也很难实施集中式管理。
图 1-1 集中式消息传送与点对点消息传送
在集中式系统(企业首选消息传送方案)中,消息服务能够在组件间进行消息路由和传送,并负责可靠且安全地进行传送。因为这种系统中的组件间是松散耦合的,所以更容易实现异步消息传送。
随着消息传送组件被不断添加到系统中,连接的数量成线性增加,这样就可以轻松地通过调整消息服务来调整系统。除连接消息传送客户机外,集中式消息服务还提供了一种管理界面,可以使用该界面来配置行为、监视性能和调节服务,以满足每个消息传送客户机的需要。
基本消息服务体系结构
图 1-2 所示为集中式消息传送系统的基本体系结构。它包括消息生产者和消息消费者,它们通过公共的消息服务来交换消息。同一消息传送组件(或应用程序)中可以保存任意数量的消息生产者和消息消费者。
消息生产者使用消息服务编程 API 将消息发送至消息服务器。消息服务器进行消息路由并将消息传送至一个或多个已注册申请此消息的消息消费者。消费者使用消息服务编程 API 来接收消息。消息服务负责保证将消息传送至所有相应的消费者。
图 1-2 消息服务体系结构
也许将这一过程比喻为交换邮件最恰当不过:尽管一封邮件上标注的是其最终收件人的地址,实际上却要通过邮局进行路由,并经由多个中转站后,才会到达收件人的邮箱。
Java 消息服务 (JMS) 基础Message Queue 是一种实现了 Java 消息服务 (JMS) 开放标准的企业消息传送系统:它是 JMS 提供者。因此,JMS 概念是理解 Message Queue 服务工作方式的基础。
JMS 规范规定了一套管理可靠异步消息传送的规则和语义。该规范定义了消息结构、编程模型和 API。
本节说明了理解本书其余各章所需的 JMS 概念和术语。涵盖下列主题:
JMS 消息结构
在 Message Queue 中,数据是使用 JMS 消息进行交换的。根据 JMS 规范,生产者客户机创建的消息包括三部分:标题、属性和主体。
标题
每条 JMS 消息都必须具有标题。标题字段包含用于路由和识别消息的值。
可以通过多种方式来设置标题的值:
有关 JMS 定义的标题字段的信息,请参见 Message Queue Developer's Guide for Java Clients 或 Message Queue Developer's Guide for C Clients。可以通过这些标题字段定义消息的目标、到期时间及其优先级等。
属性
消息可以包含称作属性的可选标题字段。它们是以属性名和属性值对的形式指定的。可以将属性视为消息标题的扩展,其中可以包括以下信息:创建数据的进程、数据的创建时间以及每条数据的结构。JMS 提供者也可以添加影响消息处理的属性,如是否应压缩消息或如何在消息生命周期结束时废弃消息。
JMS 提供者可以将消息属性用作选择器,以对消息进行排序和路由。生产者客户机可以在消息中放置特定于应用程序的属性;而消费者客户机可以选择只接收具有特定属性值的消息。例如,消费者客户机可能只请求获得有关新泽西州兼职雇员工资单的消息。不符合指定的选择标准的消息将不会传送给该客户机。
选择器简化了消费者客户机的工作,并消除了向不需要这些消息的客户机传送消息的开销。不过,由于要处理选择标准,它们也会增加消息服务的一些开销。在 JMS 规范中对消息选择器语法和语义进行了简要说明。
消息主体类型
JMS 消息的类型决定其主体的内容,如表 1-1 中所示。
JMS 编程模型
JMS 编程模型支持异步消息传送服务体系结构:JMS 客户机通过 JMS 消息服务交换消息。JMS 提供者提供执行 JMS 消息传送所需的对象;这些对象用于实现 JMS 应用程序编程接口 (API)。
本节说明 JMS 消息传送所需的编程对象,并介绍用于发送和接收消息的传送模型(点对点及发布/订阅)。
编程对象
图 1-3 中显示了用于设置 JMS 客户机以进行消息传送的对象。
图 1-3 JMS 编程对象
在 JMS 编程模型中,JMS 客户机使用连接工厂对象 (ConnectionFactory) 创建一个连接,向 JMS 消息服务器发送消息以及从 JMS 消息服务器接收消息均通过此连接来进行。连接对象 (Connection) 表示客户机与消息服务器之间的活动连接。
创建连接时,将分配通信资源以及验证客户机。这是一个相当重要的对象,大多数客户机均使用一个连接来进行所有的消息传送。
该连接用于创建会话对象 (Session)。会话是一个用于生成和使用消息的单线程上下文。它用于创建消息以及发送和接收消息的生产者和消费者,并为所传送的消息定义发送顺序。会话通过大量确认选项或通过事务来支持可靠传送。
客户机使用消息生产者对象 (MessageProducer) 向指定的物理目标(在 API 中由目标对象表示)发送消息。消息生产者可指定一个默认的消息标题值,例如,传送模式(持久性与非持久性)、优先级和有效期,以控制生产者向物理目标发送的所有消息。
同样,客户机使用消息消费者对象 (MessageConsumer) 从指定的物理目标(在 API 中表示为目标对象)接收消息。共有两种类型的目标,分别是队列和主题,具体类型取决于消息传送模型。
消息消费者可以利用消息选择器,使消息服务只传送那些属性匹配特定选择标准的消息。
消息消费者可以支持同步或异步消息使用。
编程域:消息传送模型
JMS 支持两种截然不同的消息传送模型:点对点模型和发布/订阅模型。
点对点(队列目标) 消息从一个生产者传送至单个消费者。在此传送模型中,目标类型是队列。消息首先被传送至队列目标,然后从该队列将消息传送至对此队列进行注册的某个消费者,一次只传送一条消息。可以向队列目标发送消息的生产者的数量没有限制,但每条消息只能发送至、并由一个消费者成功使用。如果没有已经向队列目标注册的消费者,队列将保留它收到的消息,并在某个消费者对该队列进行注册时将消息传送给该消费者。
发布/订阅(主题目标) 消息从一个生产者传送至任意数量的消费者。在此传送模型中,目标类型是主题。消息首先被传送至主题目标,然后传送至所有已订阅此主题的活动消费者。可以向主题目标发送消息的生产者的数量没有限制,并且每个消息可以发送至任意数量的订阅消费者。
主题目标也支持长期订阅。长期订阅表示消费者已注册了主题目标,但在消息到达目标时该消费者可以处于非活动状态。当消费者再次处于活动状态时,将会接收该消息。如果消费者均没有注册某个主题目标,该主题只保留注册了长期订阅的非活动消费者的消息。
这两种消息传送模型使用三组表示不同编程域的 API 对象(其语义略有不同)进行处理,如表 1-2 所示。
表 1-2 JMS 编程域和对象
基本类型(统一域)
点对点域
发布/订阅域
Destination(Queue 或 Topic)1
Queue
Topic
ConnectionFactory
QueueConnectionFactory
TopicConnectionFactory
Connection
QueueConnection
TopicConnection
Session
QueueSession
TopicSession
MessageProducer
QueueSender
TopicPublisher
MessageConsumer
QueueReceiver
TopicSubscriber
1取决于编程方法,您必须指定特定的目标类型。
JMS 版本 1.1 中引入了统一域。如果需要遵循早期的 1.02b 规范,可以使用特定于域的 API。使用特定于域的 API 还具有编程接口为全新接口的优点,可以防止出现某些类型的编程错误:例如,为队列目标创建长期订户。不过,特定于域的 API 也有缺点,即无法合并同一事务或会话中的点对点操作及发布/订阅操作。如果需要执行该操作,则应选择统一的域 API。
Message Queue 产品包含的示例应用程序以及 Message Queue 文档中提供的很多代码示例均使用单独的编程域。
可靠消息传送
可以将消息的传送模式设置为持久性或非持久性;此模式控制消息传送的可靠性。
对于持久性消息,确保可靠性有两个方面。一方面,通过使用确认和事务来确保成功生成和使用消息。另一方面,通过将消息放在持久性存储库中,确保在将持久性消息传送至消费者之前消息服务不会丢失持久性消息。
以下各节介绍这两个方面的可靠性保证措施。
确认/事务
可靠的消息传送取决于保证成功地将持久性消息从消息生产者传送到消息服务器上的物理目标,然后再成功地从该物理目标传送到消息消费者。这种可靠性可以通过 JMS 会话支持的两个通用机制实现:确认或事务。事务可以是本地事务或分布式事务(由分布式事务管理器控制)。
确认
确认是在客户机与消息服务间发送的消息,用于确保可靠地进行传送。
生成消息时,消息服务确认它已收到传送的消息,将该消息置于其目标中并进行持久性存储。生产者的 send() 方法会阻塞,直至确认返回为止。
使用消息时,客户机确认已收到从某个目标传送来的消息并已使用,然后消息服务从该目标中删除消息。JMS 规定了不同的确认模式,它们分别代表不同的可靠性级别。在其中的某些模式下,客户机会阻塞,等待消息服务器确认已删除某个消息,并因此无法重新传送该消息。
本地事务
可以将会话配置为已处理,这样,可以将一个或多个消息的生成和/或使用组成原子单元,也就是事务。JMS API 提供了启动、提交或回滚事务的方法。
在事务中生成或使用消息时,消息服务跟踪各个发送和接收过程,并在 JMS 客户机发出提交事务的调用时完成这些操作。如果事务中特定的发送或接收操作失败,则出现异常。客户机代码通过忽略异常、重试操作或回滚整个事务来处理异常。在事务提交时,将完成其所有操作。在事务进行回滚时,将取消所有成功的操作。
本地事务的范围始终为一个会话。也就是说,可以将单个会话的上下文中执行的一个或多个生产者或消费者操作组成一个本地事务。
由于事务的范围只能为单个的会话,因此不存在既包括消息生成又包括消息使用的端对端事务。(换句话说,至目标的消息传送和随后进行的至客户机的消息传送不能放在同一个事务中。)
分布式事务
JMS 规范还支持分布式事务。也就是说,消息的生成和使用可作为较大的分布式事务的一部分,该分布式事务中包括涉及其他资源管理器(如数据库系统)的操作。在分布式事务中,分布式事务管理器使用在 Java 事务 API (JTA)、XA 资源 API 规范中定义的两阶段提交协议跟踪和管理由多个资源管理器(如消息服务和数据库管理器)执行的操作。在 Java 中,JTA 规范说明了资源管理器和分布式事务管理器之间的交互。
支持分布式事务是指消息传送客户机可通过 JTA 定义的 XAResource 接口参与分布式事务。此接口定义了实现两阶段提交的许多方法。当客户机端进行 API 调用时,JMS 消息服务只与分布式事务管理器(由 Java 事务服务 (JTS) 提供)协作来跟踪分布式事务中的各种发送和接收操作、事务状态并完成消息传送操作。
处理本地事务时,客户机通过忽略异常、重试操作或回滚整个分布式事务来处理异常。
持久性存储器
另一方面的可靠性就是确保在将持久性消息传送至消费者之前,消息服务不会将它们丢失。这意味着,当持久性消息到达其物理目标时,消息服务器必须将其置于持久性数据存储库中。如果消息服务器由于某种原因发生故障,它可以恢复此消息并将其传送至相应的消费者。
消息服务器还必须持久性地存储长期订阅。否则,当消息服务器发生故障时,就无法向长期订户传送消息;消息到达主题目标后,长期订户会恢复活动状态。
要保证成功传送消息,消息传送应用程序必须将消息指定为持久性消息,并将它们传送给具有长期订阅的主题目标或传送给队列目标。
JMS 受管理对象
JMS 编程模型中使用的两个对象(连接工厂和目标)可能会因提供者的 JMS 规范实现而有所不同。
为使提供者在定义这些对象时具有最大限度的灵活性,同时使客户机具有移植性,JMS 规范定义了受管理对象(针对连接工厂和目标),其中封装了特定于提供者的信息。这些对象由管理员创建和配置,并存储在 JNDI 名称空间(对象存储库)中,由客户机通过标准 JNDI 查找代码来访问。
受管理对象允许 JMS 客户机使用逻辑名称查找和引用特定于提供者的对象。这样,客户机代码无需知道提供者使用的特定命名语法、寻址语法或可配置属性。从而使代码与提供者无关。
受管理对象一节提供了有关 Message Queue 中使用的受管理对象的其他信息。