![]() |
Sun ONE Message Queue, Version 3.0.1 管理员指南 |
本章介绍 Sun ONE Message Queue (MQ) 消息传送系统,其中重点说明的是系统的主要组成部分(如图 2-1 所示),并阐述了这些组成部分如何配合工作来提供可靠的消息传送。
图 2-1    MQ 系统的体系结构
![]()
MQ 消息传送系统的主要组成部分(如图 2-1 所示)包括:
- MQ 消息服务器
- MQ 客户机运行时
- MQ 被管理对象
- MQ 管理
前三个组成部分将在下面的小节中进行详细说明。最后一个部分将在第 3 章“MQ 管理”中介绍。
MQ 消息服务器
本节介绍 MQ 消息服务器(如图 2-1 所示)的各个组成部分,包括:
代理 MQ 代理为 MQ 消息传送系统提供传送服务。消息传送依赖于大量支持组件,这些组件负责处理连接服务、消息的路由和传送、持久性、安全性以及日志记录(有关详细信息,请参见代理)。消息服务器可以使用一个或多个代理实例(请参见多代理群集(企业版))。
物理目标 消息的传送过程分为两个阶段:首先从生成消息的客户机(生成方客户机)将消息发送到由代理维护的物理目标,然后再从目标发送到一个或多个使用消息的客户机(使用方客户机)。物理目标是指代理的物理内存和/或持久性存储器中的位置(有关详细信息,请参见物理目标)。
代理
在 MQ 消息传送系统中,消息传送(从生成方客户机到目标,然后再从目标到一个或多个使用方客户机)由代理(或以串连模式工作的代理实例群集)来执行。要执行消息传送,代理必须建立与客户机之间的通信通道、执行验证和授权、适当的路由消息、确保可靠传送并提供用于监视系统性能的数据。
为了实现这么多复杂的功能,代理使用了大量的各种组件,每个组件都在传送过程中担当着各自不同的角色。可以根据负荷条件、应用程序的复杂性等因素配置这些内部组件,以优化代理的性能。图 2-2 所示为主要的代理组件,表 2-1 则对这些组件进行了简要说明。
图 2-2    代理组件
![]()
下面的几个小节将详细介绍各代理组件执行的功能及其属性(可以配置这些属性来影响代理的行为)。
连接服务
MQ 代理既支持与 JMS 客户机的通信,也支持与 MQ 管理客户机的通信(请参见 MQ 管理工具)。各个服务取决于其服务类型和协议类型。
服务类型 指定服务提供的是 JMS 消息传送 (NORMAL) 服务,还是 MQ 管理 (ADMIN) 服务。
表 2-2 所示为 MQ 代理当前可提供的连接服务:
可以将代理配置为运行以上任一或全部连接服务。每个服务都具有一个线程池管理器,并向通用端口映射器服务注册它本身,如图 2-3 所示。
图 2-3    连接服务支持
![]()
每个连接服务仅在由代理的主机名和端口号指定的特定端口上可用。可以静态或动态地分配端口。MQ 提供了一个端口映射器,用于将动态分配的端口映射到不同的连接服务。端口映射器本身位于标准端口号 7676。当客户机建立与代理的连接时,首先与端口映射器进行通信,请求其所需的连接服务端口号。
在配置 jms、ssljms、admin 和 ssladmin 等连接服务时,也可以为它们分配静态端口号,但最好不要这样做。分别使用表 B-1 和表 B-3(这两个表格位于附录 B“HTTP/HTTPS 支持(企业版)”)中说明的属性来配置 httpjms 和 httpsjms 服务。
每个连接服务都是多线程的,从而支持多个连接。这些连接所需的线程在线程池中进行维护,而线程池又由线程池管理器组件来管理。通过配置线程池管理器,可以设置线程池中维护的线程的最大和最小数量。当连接需要线程时,这些线程将被添加到线程池中。当线程数量超过最小数量时,系统将关闭变为空闲状态的线程,直到达到最小阈值,以此来节省内存资源。您希望此值足够大,这样就不必不断创建新线程。如果连接负荷较重,线程数量可能会增加,直到达到线程池的最大数量。此后,连接不得不一直等待,直到某个线程可用。
线程池中的线程可专用于单个连接(专用模型),也可根据需要分配到多个连接(共享模型)。
专用模型 在专用模型中,每个与代理的连接都需要两个线程:一个专门用来处理外来消息,另一个用来处理外出消息。这样,连接的数量就被限制为线程池中最大线程数量的一半,但却提供了较高的性能。
共享模型(企业版) 在共享线程模型中,只有当发送或接收消息时,连接才会被分配到某个线程。此模型(其中多个连接共享一个线程)增加了连接服务可支持的连接的数量,从而增加了代理可支持的连接的数量,但这同时带来了某些性能开销。线程池管理器使用一组分配器线程来监视连接活动并根据需要将连接分配到线程。可以限制每个这样的分配器线程所监视的连接的数量来提高性能。
每个连接服务均支持特定的验证和授权(访问控制)功能(请参见安全性管理器)。表 2-3 所示为与连接服务相关的可配置属性。(有关配置这些属性的说明,请参见第 5 章“启动与配置代理”。)
表 2-3    连接服务属性
属性名称
说明
imq.service.activelist
按名称列出启动代理时将变为活动状态的连接服务,服务之间用逗号分隔。支持的服务包括:jms、ssljms、httpjms、httpsjms、admin 和 ssladmin。默认值:jms 和 admin
imq.service_name.
min_threads
指定线程数量,达到该数量后,线程池中将维护此数量的线程供命名的连接服务使用。默认值:取决于连接服务(请参见表 5-1)。
imq.service_name.
max_threads
指定线程数量,达到该数量后,新的线程将不会被添加到线程池中供命名的连接服务使用。该数量必须大于零,并且必须大于 min_threads 的值。默认值:取决于连接服务(请参见表 5-1)。
imq.service_name.
threadpool_model
为命名的连接服务指定线程是专用于特定的连接 (dedicated),还是根据需要由多个连接共享 (shared)。共享模型(线程池管理)将增加代理支持的连接数量,但只能用于 jms 和 admin 连接服务。默认值:取决于连接服务(请参见表 5-1)。
imq.shared.
connectionMonitor_limit
仅适用于共享线程池模型,用于指定分配器线程可监视的连接的最大数量。(系统会分配足够多的分配器线程来监视所有连接。)此值越小,系统向线程分配活动连接的速度就越快。值 0 表示没有限制。默认值:取决于操作系统(请参见表 5-1)。
imq.portmapper.port
代理的主端口,即端口映射器所在的端口。如果主机上运行多个代理实例,则必须为每个实例分配唯一的端口映射器端口。默认值: 7676
imq.service_name.
protocol_type1.port
仅适用于 jms、ssljms、admin 和 ssladmin 服务,指定命名的连接服务的端口号。默认值:0(端口由端口映射器动态分配)
要配置 httpjms 和 httpsjms 连接服务,请参见附录 B“HTTP/HTTPS 支持(企业版)”。
imq.service_name.
protocol_type1.hostname
仅适用于 jms、ssljms、admin 和 ssladmin 服务,如果有多个主机可用(例如,一台计算机中安装了多个网络接口卡),命名的连接服务将绑定到此属性指定的主机(主机名或 IP 地址)。
默认值:null(任意主机)
1 protocol_type 为表 2-2 中指定的协议类型。 消息路由器
使用支持的连接服务在客户机与代理之间建立起连接后,即可进行消息的路由和传送。
基本传送机制
广义来讲,代理处理的消息可分为两类:由生成方客户机发往使用方客户机的 JMS 消息(即有效负荷消息)以及从客户机发出或发往客户机的大量用于支持 JMS 消息传送的控制消息。
如果外来消息为 JMS 消息,代理会根据其目标的类型(队列或主题)将其发送到使用方客户机:
- 如果目标为主题,JMS 消息将立即被路由到此主题的所有活动订户。对于未处于活动状态的长期订户,消息路由器将保留消息,直到订户变为活动状态后再将消息传送给该订户。
- 如果目标为队列,JMS 消息将被放置在相应的队列中,并在到达队列前端时被传送到相应的使用方。消息到达队列前端的顺序取决于它们进入队列的顺序以及它们的优先级。
消息路由器将消息传送到其所有目标使用方后,将从内存中删除此消息。如果该消息为持久性消息(请参见可靠消息传送),还会将其从代理的持久性数据存储中删除。
可靠传送:确认和事务
如果增加可靠传送(请参见可靠消息传送)的要求,则刚才讨论的传送机制就会复杂得多。可靠传送涉及两个方面:一是确保消息成功传送到代理以及从代理成功传送出去,二是确保在实际传送消息前,代理没有丢失消息或传送信息。。
为了确保至代理和出自代理的消息传送能够成功,MQ 使用了大量称为“确认”的控制消息。
例如,当生成方向目标发送 JMS 消息(有效负荷消息而非控制消息)时,代理会发回一条说明它已接收到 JMS 消息的控制消息,这条控制消息就是代理确认。(实际上,只有当生成方将 JMS 消息指定为持久性消息时,MQ 才会进行上述操作。)生成方客户机使用代理确认来确保至目标的传送成功(请参见消息生成)。
同样,当代理将 JMS 消息传送到使用方时,使用方客户机会发回一个确认,说明它已接收并处理了此消息。客户机可以在创建会话对象时指定发送这些确认的自动程度和频率,但原则是消息路由器在收到每个消息使用方(即接收它所传送的消息的客户机,例如某个主题的每个订户)的确认之前,不会从内存中删除 JMS 消息。
对于某个主题的长期订户,消息路由器会将每条 JMS 消息保留在该目标中,以便在每个长期订户变为活动使用方时将消息传送出去。消息路由器会在接收客户机确认时进行记录,并且只有在接收到所有确认后才会删除 JMS 消息(除非在这之前 JMS 消息已过期)。
另外,消息路由器会将代理确认发送回客户机,确认已接收到客户机确认。使用方客户机使用代理确认来确保代理不会多次传送 JMS 消息(请参见消息使用)。如果由于某些原因使代理未能接收到客户机确认,则可能发生多次传送的情况。
如果代理没有接收到客户机确认并重新传送了一次 JMS 消息,此消息将被标注“重新传送”标志。通常,如果在代理接收到客户机确认之前客户机连接被关闭,并且随后又打开了新的连接,那么代理会重新传送 JMS 消息。例如,如果队列的消息使用方在确认消息之前脱机,随后另一位使用方向队列进行了注册,则代理会向该新使用方重新传送未确认的消息。
上述客户机和代理的确认过程同样适用于编组为事务的 JMS 消息传送。对于后者,客户机和代理确认在事务级别以及各个 JMS 消息发送或接收级别运行。当提交事务时,将自动发送代理确认。
代理会跟踪事务,使它们可以在出现故障时进行提交或回滚。该事务管理也支持本地事务(较大的分布式事务的一部分,请参见分布式事务)。代理会一直跟踪这些事务的状态,直到它们被提交。当代理启动时,它会检查所有未提交的事务,在默认情况下,回滚未处于 PREPARED 状态的所有事务。
可靠传送:持久性
可靠传送的另一个方面是确保在实际传送消息前,代理没有丢失消息或要传送的信息。通常,消息将始终保留在内存中,直到被传送或过期。但如果代理出现故障,这些消息将会丢失。
生成方客户机可以将消息指定为持久性消息,在这种情况下,消息路由器会将此消息传送到持久性管理器,该管理器将把消息存储在数据库或文件系统中(请参见持久性管理器),这样即使代理出现故障,消息也可以得到恢复。
管理系统资源
代理的性能取决于可用的系统资源以及资源(例如内存)的使用效率。例如,消息路由器具有用于监视系统内存的内存管理机制。当内存资源不足时,将激活释放内存并减慢外来消息流的机制。
内存管理机制取决于内存资源的状态:green(可用内存充足)、yellow(代理内存不足)、orange(代理内存严重不足)、red(代理无可用内存)。随着内存资源状态由 green 变为 yellow 再变为 orange 最后变为 red,代理所采取的措施也会越来越严格:首先是释放内存,然后是限制消息生成方,最后甚至会停止进入代理的消息流。
使用用于对内存中的消息总数以及总大小设置限制的属性以及用于调整占用阈值(达到该阈值后,内存资源将变为一个新状态)的属性,您可以配置代理的内存管理功能。
表 2-4 中详细介绍了这些属性。(有关设置这些属性的说明,请参见第 5 章“启动与配置代理”。)
表 2-4    消息路由器属性
属性名称
说明
imq.message.expiration.
interval
指定过期消息的收回频率(以秒为单位)。默认值: 60
imq.system.max_count
指定内存和磁盘中的消息最大数量(由于交换)。超出限制的消息将被拒绝。值 0 表示没有限制。默认值: 0
imq.system.max_size
指定内存和磁盘中的消息最大总大小(由于交换),以字节、千字节或兆字节为单位。超出限制的消息将被拒绝。值 0 表示没有限制。默认值: 0
imq.message.max_size
指定消息主体允许的最大大小(以字节、千字节或兆字节为单位)。任何大于此值的消息将被拒绝。值 0 表示没有限制。默认值:70m(兆字节)
imq.resource_state.
threshold
指定将触发各个内存资源状态的内存占用百分比。资源状态的值可以是 green、yellow、orange 和 red。默认值:分别为 0、60、75 和 90
imq.redelivered.
optimization
指定 (true/false) 消息路由器是在重新传送消息时通过设置重新传送标志来优化性能 (true),还是仅当逻辑上需要时这样做 (false)。默认值: true
imq.transaction.
autorollback
指定 (true/false) 当启动代理时,处于 PREPARED 状态的分布式事务是否自动回滚。如果为 false,则必须使用 imqcmd 手动提交或回滚事务(请参见管理事务)。默认值: false
持久性管理器
对于发生故障后待恢复的代理,需要重新创建其消息传送操作的状态。这需要它将所有持久性消息以及基本的路由和传送信息保存到数据存储中。持久性管理器组件用于管理此信息的写入和检索。
为了恢复出现故障的代理,不仅需要恢复未传送的消息,代理还必须完成以下操作:
- 重新创建目标
- 恢复每个主题的长期订阅列表
- 恢复每条消息的确认列表
- 重新生成所有已提交事务的状态
持久性管理器用于管理所有这些状态信息的存储和检索。
当代理重新启动时,它将重新创建目标和长期订阅,恢复持久性消息和所有事务的状态,并重新创建未传送消息的路由表。然后代理才可以恢复消息传送。
MQ 既支持内置的持久性模块,也支持插入的持久性模块(请参见图 2-4)。内置的持久性基于文本文件数据存储。插入的持久性使用 Java 数据库连接 (JDBC) 接口,并需要 JDBC 兼容的数据存储。通常,内置的持久性比插入的持久性速度更快,但某些用户更希望获得使用 JDBC 兼容的数据库系统的冗余和管理功能。
图 2-4    持久性管理器支持
![]()
内置的持久性
MQ 持久性存储器的默认解决方案是文本文件存储。该解决方案使用单个文件来存储持久性数据,例如消息、目标、长期订阅和事务等。
文本文件数据存储位于:
其中 brokerName 为标识代理实例的名称。
IMQ_VARHOME/instances/brokerName/filestore/
(在 Solaris 中为 /var/imq/instances/brokerName/filestore/)基于文件的数据存储的结构是每条持久性消息都存储在各自的文件中,每个文件存储一条消息。不过,目标、长期订阅和事务都是每一类存储到一个单独的文件中。例如,所有目标存储到一个文件,所有长期订阅存储到另一个文件,依此类推。
创建或删除文件时,因为要将消息添加到数据存储或从数据存储中删除消息,所以涉及大量的文件系统操作。因此 MQ 实现方案会重复使用这些消息文件:当不再需要某个文件时,将把它添加到可供重复使用的空闲文件池中,而不是将其删除。可以配置此文件池的大小。也可以指定文件池中空闲文件所占的百分比,达到此百分比后将清除文件池(清空),而不是仅标记这些空闲文件供重复使用(不清空)。此清除文件的百分比越高,文件池所需的磁盘空间越小,但维护文件池所需的开销就越大。另外,也可以指定关闭时是否清除标记的文件。如果清除这些文件,它们所占用的磁盘空间就会减少,但代理将需要更长的时间来进行关闭操作。
在文本文件存储中,存储消息的速度受数据存储能够使用的文件描述符数量的影响,描述符数量越多,系统处理大量持久性消息的速度就越快。有关增加文件描述符数量的信息,请参见《MQ 发行说明》中的“技术说明”一节。
另外,对于目标文件存储,更高效的做法是将目标添加到固定大小的文件中,而不是随着目标不断添加而增加文件的大小。因此,可以根据最终要存储的目标数量来设置目标文件的原始大小,从而提高性能(每个目标占用大约 500 字节)。
由于数据存储可能包含具有专利信息的消息,所以建议您对 brokerName/filestore/ 目录进行保护,以防止未获授权的访问。有关说明请参见《MQ 发行说明》中的“技术说明”一节。
插入的持久性
您可以代理进行设置,以访问可通过 JDBC 驱动程序访问的任何数据存储。这将设计到设置多个与 JDBC 相关的代理配置属性以及使用数据库管理器实用程序 (imqdbmgr) 来创建具有相应架构的数据存储。附录 A“设置插入的持久性”中详细说明了上述过程和相关的配置属性。
表 2-5 详细说明了与持久性相关的配置属性。(有关设置这些属性的说明,请参见第 5 章“启动与配置代理”。)
安全性管理器
MQ 提供验证和授权(访问控制)功能,同时也支持加密功能。
验证和授权功能取决于用户系统信息库(请参见图 2-5):包含消息传送系统的用户信息(用户名、口令和组成员资格)的文件、目录或数据库。用户名和口令用于在请求连接至代理时对用户进行验证。用户名和组成员资格(与访问控制文件配套使用)用于授权操作,例如为目标生成消息或使用目标的消息。
MQ 管理员可填充 MQ 提供的用户系统信息库(请参见使用文本文件用户系统信息库),也可以将原有的 LDAP 用户系统信息库插入到安全性管理器组件中。文本文件用户系统信息库使用起来较简单,但在安全性上也易遭攻击,因此应只将其用于测试和开发目的,而 LDAP 用户系统信息库相对较安全,因此更适合用于生产目的。
验证
MQ 安全性支持基于口令的验证。当客户机请求连接到代理时,该客户机必须提交用户名和口令。安全性管理器将把客户机提交的用户名和口令与用户系统信息库中存储的用户名和口令进行比较。口令在从客户机传送到代理的过程中,将使用 Base 64 编码或消息摘要 (MD5) 进行编码。要想获得更安全的传送,请参见加密(企业版)。可以分别配置每个连接服务使用的编码的类型,也可以基于代理范围设置编码方式。
授权
客户机应用程序的用户通过验证后,即可以获得授权来执行各种 MQ 相关的活动。安全性管理器既支持基于用户的访问控制,也支持基于组的访问控制:根据用户在用户系统信息库中分配到的用户名或组的不同,该用户所拥有的执行特定 MQ 操作的权限也不同。这些访问控制在访问控制属性文件中指定(请参见图 2-5)。
当用户尝试执行某个操作时,安全性管理器将检查该用户的用户名和组成员资格(通过用户系统信息库)是否属于被指定允许访问该操作的用户名或组成员资格(在访问控制属性文件中)。访问控制属性文件指定了执行以下操作的权限:
- 建立与代理的连接
- 访问目标:创建任意给定目标或所有目标的使用方、生成方或队列浏览器
- 自动创建目标
图 2-5    安全性管理器支持
![]()
对于 MQ 3.0.1,默认的访问控制属性文件只明确引用一个组:管理员(参见组)。管理员组中的用户拥有管理服务连接权限。管理服务使用户可以执行管理功能,例如创建目标以及监视和控制代理。默认情况下,您定义的其它任何组中的用户都无法获得管理服务连接。
作为 MQ 管理员,可以在用户系统信息库中定义组并使用户与这些组关联(虽然在文本文件用户系统信息库中不完全支持组)。然后,通过编辑访问控制属性文件,可以按照用户和组的不同目的(生成和使用消息,或浏览队列目标中的消息)指定对目标的权限。可以分别指定各个目标或指定所有目标仅能够被特定用户或组访问。
另外,如果将代理配置为允许自动创建目标(请参见自动创建的(与管理员创建的相对)目标),则可以通过编辑访问控制属性文件来控制代理可为谁自动创建目标。
加密(企业版)
要对客户机和代理之间发送的消息进行加密,需要使用基于安全套接字层 (SSL) 标准的连接服务。SSL 通过在启用 SSL 的代理与启用 SSL 的客户机之间建立加密连接来提供连接级别的安全性。
为了使用 MQ 基于 SSL 的连接服务,需要使用密钥工具实用程序 (imqkeytool) 生成专用密钥/公用密钥对。此实用程序将公用密钥嵌入自签名的证书中,并将其放入 MQ 密钥存储中。MQ 密钥存储本身设有口令保护,要解除锁定,需要在启动时提供密钥存储的口令。请参见加密:使用 SSL 服务(企业版)。
解除密钥存储的锁定后,代理即可将证书传送给所有请求连接的客户机。然后,客户机使用此证书建立与代理的加密连接。
表 2-6 所示为验证、授权、加密以及其它安全性通信的可配置属性。(有关配置这些属性的说明,请参见第 5 章“启动与配置代理”。)
表 2-6    安全性属性
属性名称
说明
imq.authentication.type
指定传送口令时应使用 Base 64 编码 (basic) 还是 MD5 摘要 (digest)。设置代理支持的所有连接服务的编码。默认值:digest
imq.service_name.
authentication.type
指定传送口令时应使用 Base 64 编码 (basic) 还是 MD5 摘要 (digest)。设置命名的连接服务的编码,此设置将覆盖任意代理范围的设置。
默认值:从 imq.authentication.type 的值继承。imq.authentication.
basic.user_repository
对于 Base 64 编码,指定用于验证的用户系统信息库的类型:基于文件 (file) 或 LDAP (ldap)。有关其它 LDAP 属性,请参见表 8-5。默认值:file
imq.authentication.
client.response.timeout
指定系统等待客户机响应来自代理的验证请求的时间(以秒为单位)。默认值:180(秒)
imq.accesscontrol.
enabled
为代理支持的所有连接服务设置访问控制 (true/false)。表明系统是否要检查已验证的用户是否如访问控制属性文件所指定,拥有使用连接服务或执行与特定目标有关的特定 MQ 操作的权限。默认值: true
imq.service_name.
accesscontrol.enabled
为命名的连接服务设置访问控制 (true/false),此设置将覆盖代理范围的设置。表明系统是否要检查已验证的用户是否如访问控制属性文件所指定,拥有使用连接服务或执行与特定目标有关的特定 MQ 操作的权限。
默认值:继承 imq.accesscontrol.enabled 属性的设置。imq.accesscontrol.file.
filename
为代理支持的所有连接服务指定访问控制属性文件的名称。文件名会指定相对于 IMQ_HOME/etc 目录的文件路径(在 Solaris 中为 /etc/imq)。默认值: accesscontrol.properties
imq.service_name.
accesscontrol.file.
filename
为命名的连接服务指定访问控制属性文件的名称。文件名会指定相对于 IMQ_HOME/etc 目录的文件路径(在 Solaris 中为 /etc/imq)。
默认值:继承由 imq.accesscontrol.file.filename 指定的设置。imq.passfile.enabled
指定 (true/false) 是否在密码文件中指定用于安全性通信的用户口令(适用于 SSL、LDAP 和 JDBC)。默认值:false
imq.passfile.dirpath
指定包含密码文件的目录的路径。
默认值:IMQ_HOME/etc(在 Solaris 中为 /etc/imq)imq.passfile.name
指定密码文件的名称。默认值:passfile
imq.keystore.property_name
适用于基于 SSL 的服务:指定与 SSL 密钥存储相关的安全性属性。请参见表 8-8。
日志记录器
代理包含大量用于监视和诊断其操作的组件。这些组件包括用于生成数据(代理代码、测量生成器和调试器)的组件以及用于通过多种输出通道(日志文件、控制台和 Solaris 系统日志)记录输出信息的日志记录器组件。图 2-6 是日志记录器的图解。
图 2-6    日志记录图解
![]()
可以打开或关闭测量数据的生成,并指定生成测量报告的频率。
还可以指定日志记录器级别范围:从最严重和最重要的信息(错误)到次要信息(测量数据)。表 2-7 所示为信息的种类(按重要性的降序排列)。
表 2-7    日志种类
种类
说明
ERROR
指出可能导致系统故障的问题的消息
WARNING
需要注意但不会导致系统故障的警报
INFO
测量及其它信息性消息的报告
要设置日志记录器级别,需要指定其中的某个种类。日志记录器将记录指定种类及所有更高级别种类的数据。例如,如果指定记录 WARNING 级别的信息,则日志记录器将记录警告信息和错误信息。
日志记录器可以将数据写入到多个输出通道:标准输出(控制台)、日志文件以及 Solaris 平台上的系统日志守护程序进程。
可以分别指定写入到每个输出通道的日志记录器的种类集。例如,如果将日志记录器级别设置为 ERROR,则可以指定只将错误和警告写入控制台,只将信息(测量数据)写入日志文件。有关配置和使用 Solaris 系统日志的信息,请参见 syslog(1M)、syslog.conf(4) 和 syslog(3C) 手册页。
对于日志文件,可以指定何时关闭日志文件并将输入转移到新文件。在日志文件达到指定的大小或生存期后,将保存该文件并创建一个新的日志文件。日志文件保存在以下位置:
IMQ_VARHOME/instances/brokerName/log/
(在 Solaris 上为 /var/imq/instances/brokerName/log /)创建新的转移日志文件时,将保留最新的 9 个日志文件的归档文件。日志文件为文本文件,依次命名为:
log.txt
log_1.txt
log_2.txt
...
log_9.txtlog.txt 是最新的文件,编号最大的文件是最早的文件。
表 2-8 所示为用于通过代理设置信息的生成和记录的可配置属性。(有关配置这些属性的说明,请参见第 5 章“启动与配置代理”。)
物理目标
MQ 消息传送基于两个传送阶段:首先,消息从生成方客户机传送到代理上的目标,然后再从代理上的目标传送到一个或多个使用方客户机。目标分两种类型(参见编程域):队列(点对点传送模型)和主题(发布/订阅传送模型)。这些目标表示代理的物理内存中的位置(外来消息在被路由到使用方客户机前将保留在其中)。
可以使用 MQ 管理工具创建物理目标(请参见管理目标)。也可以按照自动创建的(与管理员创建的相对)目标中的介绍来自动创建目标。
本节介绍这两种类型的物理目标(队列和主题)的属性和行为。
队列目标
队列目标用于点对点消息传送。在这种消息传送中,会有多个使用方在目标中注册请求,但消息最终仅传送到其中的一个使用方。当来自生成方客户机的消息到达时,它们将排成队列的形式,然后发送到使用方客户机。
队列消息的路由取决于队列的传送策略。MQ 执行三种队列传送策略:
- 单一 此队列只能将消息路由到一个消息使用方。如果第二个消息使用方尝试向队列进行注册,它将被拒绝。如果注册的消息使用方断开了连接,则不再路由消息,并且会保存这些未传送的消息,直到注册了新的使用方。
- 故障切换(企业版)此队列可以将消息路由到多个消息使用方,但只有其主消息使用方(第一个向代理注册的使用方)断开连接时,消息才会被发往其它使用方。在这种情况下,消息将被转到下一个注册的消息使用方,即消息将继续被路由到下一个注册的消息使用方,直到该使用方也出现故障,依此类推。如果没有已注册的消息使用方,消息将被保存,直到某个使用方进行注册。
- 循环(共享)(企业版)此队列可以将消息路由到多个消息使用方。假设有多个使用方向队列进行了注册,第一个进入队列的消息将路由到第一个注册的消息使用方,第二个进入队列的消息将发往第二个注册的使用方,依此类推。其它消息按此顺序分别路由到同一使用方的集合。在使用方向队列进行注册前,如果已有大量消息排队等候,则会按批发送消息以避免一齐涌向某个使用方。如果有任意消息使用方断开连接,则本应路由到该使用方的消息将在其余的活动使用方之间重新进行分配。由于进了这样的重新分配,就不能保证消息传送到使用方的顺序与它们在队列中接收消息的顺序相同。
由于消息可以在队列中保留相当长的一段时间,因此内存资源可能会成为一个问题。为队列分配内存时,您一定希望分配得恰到好处,向一个队列分配过多内存会导致内存不足,而太少的话消息就会被拒绝。出于灵活性的考虑,可以基于每个队列的负荷要求在创建队列时设置物理属性:队列消息的最大数量、分配给队列消息的最大内存和队列消息的最大大小(请参见表 6-10)。
主题目标
主题目标用于发布/订阅消息传送,在该消息传送中,消息最终将被传送到所有在目标中注册请求的使用方。当来自生成方的消息到达时,它们将被路由到所有订阅该主题的使用方。如果使用方已注册为长期订阅该主题,则当消息被传送到主题时并不需要这些使用方必须处于活动状态。代理将存储此消息,直到使用方再次处于活动状态,然后将消息传送给它。
通常,消息不会在主题目标中保留过长的时间,因此,内存资源通常也不是大问题。不过,您可以为目标收到的任意消息配置允许的最大大小(请参见表 6-10)。
自动创建的(与管理员创建的相对)目标
JMS 消息服务器是消息传送系统的核心,因此其性能和可靠性对企业应用程序的正常运行至关重要。因为目标可能消耗大量的资源(取决于它们处理的消息的数量和大小以及注册的消息使用方的数量和长期性),所以需要对它们严格地进行管理,以确保消息服务器的性能和可靠性。因此为应用程序创建目标、监视目标以及根据需要重新配置它们的资源要求已成为 MQ 管理员的标准做法。
不过,有些时候可能需要动态创建目标。例如,在开发和测试阶段,可能希望代理根据需要自动创建目标,而不需要管理员进行干预。
MQ 支持这种自动创建功能。启用自动创建后,每当 MessageConsumer 或 MessageProducer 尝试访问不存在的目标时,代理会自动创建一个目标。(客户机应用程序的用户必须拥有自动创建权限,请参见目标自动创建访问控制。)
不过,当自动(而非明确)创建目标时,可能会导致不同客户机应用程序(使用相同的目标名称)之间发生冲突,或者导致系统性能降低(由于支持目标需要消耗资源)。因此,当不再使用 MQ 自动创建的目标时,也就是当目标不再与消息使用方客户机保持连接且不再包含任何消息时,代理会自动将其销毁。重新启动代理后,只有当自动创建的目标包含持久性消息时,才会重新创建这些目标。
可以使用表 2-9 中所示的属性来配置 MQ 消息服务器,以便启用或禁用自动创建功能。(有关配置这些属性的说明,请参见第 5 章“启动与配置代理”。)
临时目标
某些客户机应用程序需要一个目标来接收对发送至其它客户机的消息的回复。这些客户机应用程序使用 JMS API 明确创建和销毁的目标称为临时目标。这些目标是为连接而创建的,并由代理维护,而且仅在连接期间存在。临时目标无法由管理员销毁,而且只要此目标在使用中(即连接有活动的消息使用方),那么它也无法由客户机应用程序销毁。临时目标与管理员创建或自动创建的目标不同(后两者包含持久性消息),它们不会被持久保存,并且在重新启动代理时也不会重新创建临时目标。此外,也无法通过 MQ 管理工具来对它们进行管理。
多代理群集(企业版)
MQ 企业版使用多个互连的代理实例(代理群集)来支持消息服务器的实现方案。群集支持为消息服务器提供了可伸缩性。
随着连接到代理的客户机数量以及所传送的消息数量的不断增加,代理最终将超出资源限制(例如文件描述符和内存限制)。适应不断增加的负荷的方法之一是将更多的代理(即更多代理实例)添加到 MQ 消息服务器,从而将客户机连接和消息传送分布到多个代理。
也可以使用多代理优化网络带宽。例如,您可能希望在一组远程代理之间使用低速的长途网络链接,而在客户机与其各自的代理之间使用高速链接进行连接。
虽然使用代理群集还有其它原因(例如,适应具有不同用户系统信息库的工作组或处理防火墙限制),但故障切换并不是其中的一个原因。群集中的某个代理不能用作其它发生故障的代理的自动备份。MQ 版本 3.0.1 不支持代理的自动故障切换保护。(不过,可以将应用程序设计为使用多代理来实现自定义的故障切换机制。)
有关配置和管理代理群集的信息,请参见使用群集(企业版)。
以下几个小节介绍了 MQ 代理群集的体系结构和内部功能。
多代理体系结构
多代理消息服务器允许将客户机连接分布在多个代理实例上,如图 2-7 中所示。从客户机的角度来看,每个客户机都连接到各自的代理(其主代理),发送和接收消息时就好像主代理是群集中唯一的代理。但从消息服务器的角度来看,主代理与群集中的其它代理串联起来进行工作,为主代理直接连接的消息生成方和使用方提供传送服务。
通常,群集中的代理可以以任意拓扑结构连接。但 MQ 版本 3.0.1 仅支持完全连接的群集,即在该拓扑结构中,每个代理都与群集中的其它所有代理直接连接,如图 2-7 所示。
图 2-7    多代理(群集)体系结构
![]()
在多代理配置中,每个目标的实例位于群集中的所有代理上。另外,每个代理都了解向所有其它代理进行注册的消息使用方。因此,每个代理既可以将消息从其直接连接的消息生成方路由到远程消息使用方,也可以从远程生成方将消息发送到其直接连接的使用方。
在群集配置中,与每个消息生成方直接连接的代理将对该直接相连的生成方发送给它的消息执行路由。因此,持久性消息是通过消息的主代理进行存储和路由的。
当管理员创建或销毁代理上的目标时,此信息会自动传播到群集中其它所有代理。同样,当消息使用方向其主代理进行注册,或当使用方与其主代理断开连接(无论是明确断开,还是因为客户机、网络故障或其主代理故障而断开),该使用方的相关信息都会被传播到整个群集。与此类似,长期订阅的相关信息也会被传播到群集中的所有代理。
注 网络繁忙和/或消息较大可能会堵塞内部群集连接。该不断增加的延迟有时还会引起锁定协议超时错误。这样,客户机在尝试创建长期订户或将消息使用方排队时可能会引发异常。通常,使用高速连接可以避免这些问题。
将目标和消息使用方的相关信息传播至特定代理时,通常要求在共享资源中进行更改时该代理处于联机状态。如果进行这样的更改时代理处于脱机状态,那么将会发生怎样的情况呢(例如,代理崩溃、随后又重新启动,或者新代理被动态添加到群集)?
为了解决脱机的代理(或添加的新代理)带来的问题,MQ 会提供一份记录,其中包括对群集中所有持久性实体的更改,即所有已创建或已销毁的目标和长期订阅的记录。代理被动态添加到群集后,首先从此配置更改记录中读取目标和长期订户信息,当它进入联机状态后,将与其它代理交换当前活动使用方的相关信息。通过这些信息,新的代理将完全集成到群集中。
配置更改记录由群集中的一个代理(即指定为主管代理的代理)进行管理。因为主管代理是向群集动态添加代理的关键,所以应始终先启动此代理。如果主管代理未联机,则群集中的其它代理将无法完成初始化。
如果主管代理脱机,而其它代理又无法访问配置更改记录,则 MQ 将不允许在群集中传播目标和长期订阅。此时,如果尝试创建或销毁目标和长期订阅(或尝试大量相关操作,例如重新激活长期订阅),将引发异常。
在关键任务的应用程序环境中,最好定期备份配置更改记录,以避免因记录意外损坏或主管代理故障带来的损失。可以使用 imqbrokerd 命令的 -backup 选项(此选项用于创建包含配置更改记录的备份文件,请参见表 5-2)来完成上述备份。然后可以使用 -restore 选项来恢复配置更改记录。
如果需要,可以更改用作主管代理的代理,更改方法为:备份配置更改记录,修改相应的群集配置属性(请参见表 2-10)以指定新的主管代理,然后使用 -restore 选项重新启动新的主管代理。
在开发环境中使用群集
在开发环境中,群集用于测试,而且可伸缩性和代理恢复不是很重要,因此基本不需要主管代理。在配置为没有主代理的环境中,MQ 不再要求必须运行主管代理才能启动其它代理,并允许对目标和长期订阅进行更改,并且可以在群集的所有运行代理中传播更改。如果代理脱机、随后又恢复,它将不会与脱机期间所作的更改同步。
在测试环境下,通常自动创建目标(请参见自动创建的(与管理员创建的相对)目标),并且由正在测试的应用程序创建和销毁这些目标的长期订阅。目标和长期订阅中的这些更改将在整个群集中传播。但是,如果将环境重新配置为使用主管代理,则 MQ 将重新强制要求必须运行主管代理才能更改目标和长期订阅并在整个群集中传播这些更改。
群集配置属性
启动时,群集中的每个代理都必须接收到有关群集中其它代理的信息(主机名和端口号)。此信息用于在群集中的代理之间建立连接。另外,每个代理也必须知道主管代理(如果使用)的主机名和端口号。
群集中的所有代理应使用相同的群集配置属性。为此,可以将它们放入一个中心群集配置文件,启动时每个代理均会引用该文件。
(也可以复制这些配置属性,然后分别为每个代理提供这些属性。但最好不要采用这种做法,因为这会导致群集配置中出现不一致。只保留一份群集配置属性可以确保所有代理获得相同的信息。)
表 2-10 所示为 MQ 群集配置属性。(有关设置这些属性的说明,请参见使用群集(企业版)。)
群集配置文件可以用于存储一组代理通用的所有代理配置属性。虽然,它原本是用来配置群集的,但也可以用来存储群集中所有代理通用的其它代理属性。
MQ 客户机运行时
MQ 客户机运行时向客户机应用程序提供至 MQ 消息服务器的接口,即向客户机应用程序提供 JMS 编程模型中介绍的所有 JMS 编程对象。它支持客户机向目标发送消息以及接收来自这些目标的消息所需的所有操作。
本节提供 MQ 客户机运行时的工作方式的高级说明。《MQ 开发者指南》中介绍了影响其性能的因素,因为它们也是影响客户机应用程序的设计和性能的因素。
图 2-8 说明了在消息的生成和使用中客户机应用程序如何与 MQ 客户机运行时之间进行交互以及在消息传送中 MQ 客户机运行时如何与 MQ 消息服务器之间进行交互。
图 2-8    消息传送操作
![]()
消息生成
在消息生成中,由客户机创建消息,然后通过连接将消息发送至代理中的目标。如果将 MessageProducer 对象的消息传送模式设置为持久性(有保证的传送,传送一次且仅传送一次),客户机线程将阻塞,直到代理确认消息已传送到其目标并存储在代理的持久性数据存储中为止。如果消息不是持久性的,则代理不会返回代理确认消息(在属性名称中称为“Ack”),并且客户机线程不会阻塞。
消息使用
消息的使用要比生成复杂得多。在以下条件下,将把到达代理中的目标的消息通过连接传送到 MQ 客户机运行时:
- 客户机已经设置了给定目标的使用方
- 使用方的选择条件(如果存在)与到达给定目标的消息的选择条件匹配
- 已告知连接开始传送消息。
通过连接传送的消息将分发到相应的 MQ 会话,在这些会话中,它们排队等待供相应的 MessageConsumer 对象使用,如图 2-9 所示。每次从每个会话队列中取出一条消息(会话是单线程的),然后同步使用(通过调用 receive 方法的客户机线程)或异步使用(通过调用 MessageListener 对象的 onMessage 方法的客户机线程)消息。
图 2-9    将消息传送到 MQ 客户机运行时
![]()
代理在向客户机运行时传送消息时,会对消息进行相应地标记,但无法实际得知这些消息是否已被接收或使用。因此,只有客户机确认接收到消息后,代理才会将消息从其目标中删除。
MQ 被管理对象
被管理对象可以使客户机应用程序代码与提供者无关。为此,它们需要将提供者特有的实现方案和配置信息封装在对象中,而客户机应用程序可以通过与提供者无关的方式使用这些对象。被管理对象由管理员创建和配置,并存储在命名服务中,由客户机应用程序通过标准 JNDI 查找代码来访问。
MQ 提供两种类型的被管理对象:ConnectionFactory(连接工厂)和 Destination(目标)。虽然两者都用于封存提供者特有的信息,但在客户机应用程序中,它们的用途却有很大的差异。ConnectionFactory 对象用于创建至消息服务器的连接,而 Destination 对象用于标识物理目标。
通过被管理对象,可以非常容易地控制和管理 MQ 消息服务器:
- 您可以通过要求客户机应用程序访问预配置的 ConnectionFactory 对象来控制连接的行为(请参见被管理对象的属性)。
- 您可以通过要求客户机应用程序访问与现有物理目标对应的预配置 Destination 对象来控制物理目标的创建。(您还需要禁用代理的自动创建功能,请参见自动创建的(与管理员创建的相对)目标。)
- 您可以通过覆盖由客户机应用程序设置的消息标题值来控制 MQ 消息服务器资源(请参见被管理对象的属性)。
因此,被管理对象使您(MQ 管理员)可以控制消息服务器配置的详细信息,同时又可以使客户机应用程序与提供者无关:它们不需要了解提供者特有的语法和对象命名惯例(请参见 JMS 提供者无关)或提供者特有的配置属性。
请使用 MQ 管理工具来创建被管理对象,如第 7 章“管理被管理对象”中所述。创建被管理对象时,可以将对象指定为只读,也就是说,不允许客户机应用程序更改 MQ 特有的配置值(即在创建对象时设置的值)。换句话说,客户机代码无法设置只读被管理对象的属性值,而且也无法使用客户机应用程序的启动选项覆盖这些值,如在客户机启动时覆盖属性值中所述。
虽然客户机应用程序可以独立地实例化 ConnectionFactory 和 Destination 这两种被管理对象,但这样会削弱被管理对象的基本用途(即使 MQ 管理员 可以控制应用程序所需的代理资源以及调节其性能的用途)。另外,直接实例化被管理对象将使客户机应用程序成为提供者特有的应用程序,而无法实现与提供者无关。
“连接工厂”被管理对象
ConnectionFactory 对象用于建立客户机应用程序与 MQ 消息服务器之间的物理连接,还可用于指定连接的行为以及使用此连接访问代理的客户机运行时的行为。
如果要支持分布式事务(请参见本地事务),需要使用支持分布式事务的特殊的 XAConnectionFactory 对象。
要创建 ConnectionFactory 被管理对象,请参见添加连接工厂。
通过配置 ConnectionFactory 被管理对象,可以指定该对象生成的所有连接通用的属性值(属性)。ConnectionFactory 和 XAConnectionFactory 对象共享同一属性集。按照其影响的行为,这些属性可分为多个种类:
- 连接规范
- 自动重新连接行为
- 客户机标识
- 消息标题覆盖
- 可靠性和流控制
- 队列浏览器行为
- 应用程序服务器支持
- JMS 定义的属性支持
每个种类及其相应属性将在《MQ 开发者指南》中进一步讨论。虽然作为 MQ 管理员,可能会要求您调整这些属性的值,但通常是由应用程序开发者来决定需要调整哪些属性以调节客户机应用程序的性能。表 7-3 按字母顺序概述了这些属性。
Destination 被管理对象
Destination 被管理对象表示代理中与公开命名的 Destination 对象对应的物理目标(队列或主题)。表 2-11 中列出了它的两个属性。通过创建 Destination 对象,可以使客户机应用程序的 MessageConsumer 和/或 MessageProducer 对象能够访问相应的物理目标。要创建 Destination 被管理对象,请参见添加主题或队列。
在客户机启动时覆盖属性值
像使用任何 Java 应用程序一样,您可以使用命令行来启动消息传送应用程序以指定系统属性。此机制也可以用来覆盖客户机应用程序代码中使用的被管理对象的属性值。例如,可以覆盖在客户机应用程序代码中通过 JNDI 查找来访问的被管理对象的配置。
要在客户机应用程序启动时覆盖被管理对象的设置,请使用以下命令行语法:
java [[-Dattribute=value ]...] clientAppName
其中,attribute 与连接工厂被管理对象中记录的任意 ConnectionFactory 被管理对象的属性相对应。
例如,如果希望客户机应用程序连接到其它代理,而不是连接到在客户机代码中访问的 ConnectionFactory 被管理对象中指定的代理,可以使用命令行覆盖来启动客户机应用程序以设置另一个代理的 imqBrokerHostName 和 imqBrokerHostPort。
如果已将被管理对象设置为只读,则无法使用命令行覆盖来更改其属性的值。所有此类覆盖将被忽略。