Sun Java System Message Queue 3.7 UR1 管理指南

第 2 部分 管理任务

第 3 章 启动代理和客户端

安装 Sun Java SystemTM Message QueueTM 并执行一些准备步骤后,即可开始启动代理和客户端。 代理的配置是由一组配置文件控制的,传递给代理实用程序 (imqbrokerd) 的命令行选项可以覆盖这些配置文件;有关详细信息,请参见第 4 章,配置代理

本章包含以下几节:

准备系统资源

在启动代理之前,需要执行两项系统级别的准备任务:同步系统时钟,以及(在 Solaris 或 Linux 平台上)设置文件描述符限制。 以下各节介绍了这些任务。

同步系统时钟

在启动任何代理或客户端之前,同步将要与 Message Queue 系统进行交互的所有主机的时钟至关重要。如果使用消息到期(生存时间)功能,则同步尤为重要。来自未同步时钟的时间戳可能会使消息到期功能无法按预期方式工作,并且可能会使消息无法传送。同步对于代理群集同样至关重要。

应该对系统进行配置以运行时间同步协议,如简单网络时间协议 (Simple Network Time Protocol, SNTP)。通常,Solaris 和 Linux 中的 xntpd 守护进程以及 Windows 中的 W32Time 服务支持时间同步。 (有关配置此服务的信息,请参见操作系统文档。)代理运行后,要避免往回设置系统时钟。

设置文件描述符限制

在 Solaris 和 Linux 平台上,运行客户端或代理的 shell 对进程可以使用的文件描述符数量的限制不是很严格。在 Message Queue 中,客户端创建的每个连接或代理接受的每个连接都使用其中一个文件描述符。每个具有持久性消息的物理目的地也使用文件描述符。

因此,文件描述符限制限定了代理或客户端可以具有的连接数。默认情况下,Solaris 最多可具有 256 个连接,Linux 最多可具有 1024 个连接。(在实践中,由于将文件描述符用于持久性,因此连接限制实际上低于此值。)如果您需要的连接数高于此值,则必须提高将要执行客户端或代理的每个 shell 中的文件描述符限制。有关如何执行此操作的信息,请参见 ulimit 手册页。

启动代理

可以使用 Message Queue 命令行实用程序或 Windows 的“开始”菜单以交互方式启动代理,也可以安排在系统启动时自动启动代理。 以下各节介绍了操作方法。

以交互方式启动代理

也可以使用代理实用程序 (imqbrokerd) 从命令行中以交互方式启动代理。 (或者,也可以从 Windows 的“开始”菜单中启动代理。)但不能使用管理控制台 (imqadmin) 或命令实用程序 (imqcmd) 启动代理;只有在代理已经运行后才能使用这些工具。

在 Solaris 和 Linux 平台上,代理实例必须始终由最初启动该实例的用户启动。 每个代理实例都有其自身的一组配置属性和基于文件的消息存储库。首次启动代理实例时,Message Queue 将使用用户的文件创建模式掩码 (umask ) 来设置该代理实例的配置信息和持久性数据所在目录的权限。

默认情况下,代理实例具有实例名称 imqbroker。要从命令行中使用此名称和默认配置启动代理,只需使用以下命令:

imqbrokerd

此命令使用端口映射器的默认端口 7676 启动本地计算机上名为 imqbroker 的代理实例(请参见端口映射器)。

要指定非默认的实例名称,请使用 imqbrokerd 命令的 - name 选项。以下命令启动实例名称为 myBroker 的代理:

imqbrokerd -name myBroker

imqbrokerd 命令行中,还可以使用其他选项来控制代理操作的各个方面。 下面的示例使用 - tty 选项向命令窗口发送错误消息和警告(标准输出):

imqbrokerd -name myBroker -tty

也可以在命令行中使用 -D 选项来覆盖在代理实例配置文件 (config.properties) 中指定的属性值。 下面的示例设置 imq.jms.max_threads 属性,将 jms 连接服务可用的最大线程数提高到 2000:

imqbrokerd -name myBroker -Dimq.jms.max_threads=2000

有关 imqbrokerd 命令的语法、子命令和选项的完整信息,请参见代理实用程序。要了解此信息的简要概述,请输入以下命令:

imqbrokerd -help

注 –

如果您具有 Sun Java System Message Queue Platform Edition 许可证,则可以使用 imqbrokerd 命令的 - license 选项来激活试用版 Enterprise Edition 许可证,它允许您试用 Enterprise Edition 功能 90 天。 指定 try 作为许可证名称:

imqbrokerd -license try

每次启动代理时都必须使用此选项,否则,代理将默认使用标准 Platform Edition 许可证。


自动启动代理

可以将代理设置为在系统启动时自动启动,而不是在命令行中明确启动它。 具体操作方法取决于运行代理的平台(Solaris、Linux 或 Windows)。

在 Solaris 和 Linux 上自动启动

在 Solaris 和 Linux 系统上,使代理可以自动启动的脚本在 Message Queue 安装期间放在 /etc/rc* 目录树中。 要允许使用这些脚本,您必须按如下所示编辑配置文件 /etc/imq/imqbrokerd.conf (Solaris) 或 /etc/opt/sun/mq/imqbrokerd.conf (Linux):

在 Windows 上自动启动

要在 Windows 系统启动时自动启动代理,必须将代理定义为 Windows 服务。 代理将在系统启动时启动并在后台运行,直到系统关闭。因此,不要使用 imqbrokerd 命令启动代理,除非您希望启动其他实例。

系统最多只能有一个作为 Windows 服务运行的代理。任务管理器将此类代理作为两个可执行进程列出:

在 Windows 系统上,可以在安装 Message Queue 时将代理作为服务安装。 安装后,可以使用服务管理器实用程序 (imqsvcadmin) 执行以下操作:

要将启动选项传递给代理,请使用 imqsvcadmin 命令的 -args 参数。其工作方式与 imqbrokerd 命令的 -D 选项相同,如启动代理中所述。可以照常使用命令实用程序 (imqcmd) 来控制代理操作。

有关 imqsvcadmin 命令的语法、子命令和选项的完整信息,请参见服务管理器实用程序

重新配置代理服务

重新配置作为 Windows 服务安装的代理的过程如下:

Procedure重新配置作为 Windows 服务的代理

  1. 停止服务。

    1. 在 Windows“开始”菜单的“设置”子菜单中选择“控制面板”。

    2. 打开“管理工具”控制面板。

    3. 使用以下方法运行“服务”工具:选择该工具的图标,然后从“文件”菜单或弹出的上下文菜单中选择“打开”,或者仅双击该图标即可。

    4. 在“服务(本地)”下,选择 "Message Queue Broker" 服务,然后从“动作”菜单中选择“属性”。

      或者,也可以在 "Message Queue Broker" 上单击鼠标右键,然后从弹出的上下文菜单中选择“属性”,或者仅双击 "Message Queue Broker" 即可。无论在哪种情况下,都会显示“Message Queue Broker 属性”对话框。

    5. 在“属性”对话框中的“常规”选项卡下,单击“停止”以停止代理服务。

  2. 删除服务。

    在命令行中输入以下命令:


    imqsvcadmin remove
  3. 重新安装服务,并使用 -args 选项指定不同的代理启动选项,或使用 -vmargs 选项指定不同的 Java 版本参数。

    例如,要将服务的主机名和端口号分别更改为 broker1 7878,可以使用以下命令:


    imqsvcadmin install -args "-name broker1 -port 7878"

使用可选 Java 运行时环境

可以使用 imqsvcadmin 命令的 -javahome-jrehome 选项指定可选 Java 运行时环境的位置。 (还可以在服务“属性”对话框“常规”选项卡下的“启动参数”字段中指定这些选项。)


注 –

“启动参数”字段将反斜杠字符 (\) 视为转义符,因此在将反斜杠用作路径分隔符时必须键入两次, 例如,

-javahome c:\\j2sdk1.4.0

显示代理服务启动选项

要确定代理服务的启动选项,请使用 imqsvcadmin 命令的 query 选项,如示例 3–1 中所示。


示例 3–1 显示代理服务启动选项


imqsvcadmin query

Service Message Queue Broker is installed.
Display Name: Message Queue Broker
Start Type: Automatic
Binary location: C:\\Sun\\MessageQueue\\bin\\imqbrokersvc.exe
JavaHome: c:\\j2sdk1.4.0
Broker Args: -name broker1 -port 7878


服务启动问题疑难解答

如果试图启动作为 Windows 服务的代理时出现错误,您可以查看记录的错误事件:

Procedure查看记录的服务错误事件

  1. 打开 Windows 的“管理工具”控制面板。

  2. 启动“事件查看器”工具。

  3. 选择“应用程序事件日志”。

  4. 从“动作”菜单中选择“刷新”以显示所有错误事件。

删除代理

删除代理的过程也因平台而异,如以下各节所述。

删除 Solaris 或 Linux 上的代理

要删除 Solaris 或 Linux 平台上的代理实例,可以在 imqbrokerd 命令中使用 -remove 选项。命令的格式如下:

imqbrokerd [options…] -remove instance

例如,如果代理名称为 myBroker,则此命令应为:

imqbrokerd -name myBroker -remove instance

此命令将删除指定代理的整个实例目录。

如果将代理设置为在系统启动时自动启动,请编辑配置文件 /etc/imq/imqbrokerd.conf (Solaris) 或 /etc/opt/sun/mq/imqbrokerd.conf (Linux),将 AUTOSTART 的属性设置为 YES

有关 imqbrokerd 命令的语法、子命令和选项的完整信息,请参见代理实用程序。要了解此信息的简要概述,请输入以下命令:

删除 Windows 代理服务

要删除作为 Windows 服务运行的代理,请使用以下命令:

imqcmd shutdown bkr

关闭代理,随后使用以下命令删除服务:

imqsvcadmin remove

或者,也可以使用 Windows 的“服务”工具(可通过“管理工具”控制面板访问)来停止和删除代理服务。

删除代理服务后请重新启动计算机。

启动客户端

启动客户端应用程序之前,请向应用程序开发者了解有关如何设置系统的信息。 如果要启动 Java 客户端应用程序,则必须正确设置 CLASSPATH 变量,并确保安装了正确的 .jar 文件。Message Queue Developer's Guide for Java Clients 中包含有关系统设置常规步骤的信息,但开发者可能会提供额外信息。

要启动 Java 客户端应用程序,请使用以下命令行格式:

java clientAppName

要启动 C 客户端应用程序,请使用应用程序开发者提供的格式。

应用程序文档应提供有关应用程序设置的属性值的信息;您可能希望通过命令行覆盖其中某些属性值。 您可能还希望在命令行中为使用 Java 命名和目录接口 (Java Naming and Directory Interface, JNDI) 查找来查找连接工厂的任何 Java 客户端指定属性。如果查找返回的连接工厂比应用程序旧,则该连接工厂可能不支持较新的属性。在这种情况下,Message Queue 将这些属性设置为默认值;如有必要,可以使用命令行覆盖这些默认值。

要从命令行中为 Java 应用程序指定属性值,请使用如下语法:

java [[-Dattribute=value]
] clientAppName

attribute 的值必须是连接工厂受管理对象属性,如第 16 章,受管理对象属性参考中所述; 如果值中包含空格,请在命令行 attribute=value 部分的两端加上引号。

以下示例将启动一个名为 MyMQClient 的客户端应用程序,该示例连接到主机 OtherHost 上位于端口 7677 的代理:

java -DimqAddressList=mq://OtherHost:7677/jms MyMQClient

在命令行上指定的主机名和端口会覆盖应用程序自身设置的任何其他主机名和端口。

在某些情况下无法使用命令行来指定属性值。管理员可以将受管理对象设置为只允许读取访问,应用程序开发者也可以通过对客户端应用程序进行编码来实现此目的。与应用程序开发者进行沟通非常必要,这有助于了解启动客户端程序的最佳途径。

第 4 章 配置代理

代理配置由一组配置文件以及在启动时传递给 imqbrokerd 命令的选项控制。本章介绍了可用的配置属性以及如何使用它们来配置代理。

本章包含以下各节:

有关代理配置属性的完整参考信息,请参见第 14 章,代理属性参考

代理服务

代理配置属性可以分为几种类别,具体取决于它们所影响的服务或代理组件:

以下各节介绍了上述每个服务,并介绍了可用于根据特定需要自定义这些服务的属性。

连接服务

消息代理可以提供各种连接服务,这些连接服务使用各种传输协议来支持应用程序客户端和管理客户端。 连接属性中列出了与连接服务相关的代理配置属性。

表 4–1 显示了可用的连接服务,这些服务可以通过以下两个特性进行区分:

表 4–1 Message Queue 连接服务

服务名称 

服务类型 

协议类型

jms

NORMAL

TCP

ssljms (Enterprise Edition)

NORMAL

TLS(基于 SSL 的安全性)

httpjms (Enterprise Edition)

NORMAL

HTTP

httpsjms (Enterprise Edition)

NORMAL

HTTPS(基于 SSL 的安全性)

admin

ADMIN

TCP 

ssladmin

ADMIN

TLS(基于 SSL 的安全性) 

通过设置代理的 imq.service.activelist 属性,可以将其配置为运行上述任意或全部连接服务。此属性的值是一个连接服务列表,当代理启动时,会激活该列表中的连接服务;如果未明确指定此属性,则默认情况下将激活 jms admin 服务。

每个连接服务还支持特定的验证和授权功能;有关详细信息,请参见安全服务

端口映射器

每个连接服务仅在由主机名(或 IP 地址)和端口号指定的特定端口上可用。 您可以明确地为服务指定静态端口号,也可以让代理的端口映射器动态指定端口号。端口映射器自身驻留在代理的主端口上,该端口通常位于标准端口号 7676 上。(如果需要,您可以通过代理配置属性 imq.portmapper.port,用其他端口号来覆盖标准端口号。) 默认情况下,每个连接服务在启动时都在端口映射器中注册自身。当客户端创建与代理的连接时,Message Queue 客户端运行时环境首先与端口映射器联系,为所需的连接服务请求端口号。

或者,也可以使用 imq.serviceName.protocolType. port 配置属性(其中 serviceNameprotocolType 标识特定的连接服务, 如表 4–1 中所示)来覆盖端口映射器的设置,并明确地为连接服务指定一个静态端口号。(只有 jms ssljmsadminssladmin 连接服务可以通过这种方式进行配置;httpjmshttpsjms 服务使用不同的配置属性,如附录 C,HTTP/HTTPS 支持 中所述。)但是,静态端口通常仅在特殊情况下(例如要穿过防火墙建立连接)使用(请参见通过防火墙连接),建议不要在一般情况下使用静态端口。


注 –

如果有两个或更多的主机可用(例如,在一台计算机中安装了多个网卡),则可以使用代理属性来指定连接服务应该绑定到哪个主机。 imq.hostname 属性为所有连接服务指定一个默认主机;如果需要,以后可以使用 imq.serviceName. protocolType.hostname (对于 jms ssljmsadminssladmin 服务)或imq.portmapper.hostname(对于端口映射器自身)来覆盖此默认值。


如果同时收到多个端口映射器请求,则它们将存储在操作系统后备队列 (backlog) 中等待操作。 imq.portmapper.backlog 属性指定后备队列中的请求的最大数量。 如果超过此限制,随后的任何请求都将被拒绝,直到后备队列中的请求减少。

线程池管理

每个连接服务都是多线程的,因此可以支持多个连接。这些连接所需的线程由代理在每个服务的单独线程池中维护。当连接需要某些线程时,这些线程即添加到支持该连接的服务的线程池中。

您选择的线程模型指定了线程是专用于单个连接还是由多个连接共享:

代理的 imq.serviceName. threadpool_model 属性指定了为给定连接服务使用两个模型中的哪一个。此属性接受两个字符串值中的一个:dedicatedshared。如果未明确设置此属性,则默认情况下采用 dedicated

还可以通过设置代理属性 imq.serviceName. min_threadsimq.serviceName. max_threads 来指定服务线程池中的最小线程数和最大线程数。 当可用线程数超过指定的最小阈值时, Message Queue 将在线程变为空闲状态时将其关闭,直到再次达到最小阈值,以此来节省内存资源。 如果负载较重,线程数可能会增加,直到达到线程池的最大数量;此后,新的连接将被拒绝,直到某个线程变得可用。

共享线程模型使用分配器线程为活动连接指定线程。 代理属性 imq.shared.connectionMonitor_limit 指定单个分配器线程可以监视的最大连接数。 此属性的值越小,为连接指定线程的速度越快。imq.ping.interval 属性指定代理定期测试 ("ping") 连接(以验证该连接是否仍然处于活动状态)的时间间隔(以秒为单位)。通过这种定期测试,可以尽早检测出连接故障,以免在尝试传输消息时失败。

路由服务

客户端连接到代理之后,即可开始路由和传送消息。 在这个阶段,代理负责创建和管理不同类型的物理目的地,确保消息流畅通,以及有效地使用资源。您可以使用路由属性中介绍的代理配置属性,根据应用程序的需要以相应方式来管理这些任务。

代理的性能和稳定性取决于可用的系统资源(如内存)以及资源的使用效率。 可以设置配置属性,以防止代理因传入消息太多而过载,或者耗尽内存。这些属性在三种不同的级别上起作用,使消息服务在资源不足时仍可正常运行:

触发这些系统内存阈值表明系统范围和目的地级别的消息限制设置得过高。由于内存阈值无法始终及时地捕获潜在的内存过载,因此不应该依赖它们来控制内存使用,而应重新配置系统范围和目的地级别的限制以优化内存资源。

持久性服务

代理在发生故障后进行恢复时,需要重新创建消息传送操作的状态。 要执行此操作,代理必须将状态信息保存到持久性数据存储库中。代理在重新启动后,将使用保存的数据重新创建目的地和长期订阅,恢复持久性消息,回滚打开的事务,并为未传送的消息重新生成路由表。 然后它才能恢复消息传送。

Message Queue 既支持基于文件的持久性模块,也支持基于 JDBC 的持久性模块(请参见图 4–1)。基于文件的持久性存储使用单个文件来存储持久性数据;基于 JDBC 的持久性存储使用 Java 数据库连接 (Java Database Connectivity, JDBC™) 接口将代理连接到符合 JDBC 的数据存储库。虽然基于文件的持久性存储通常比基于 JDBC 的持久性存储快,但某些用户更希望使用 JDBC 存储库所提供的冗余和管理控制功能。代理配置属性 imq.persist.store(请参见表 14–4)指定使用两种持久性形式中的哪一种。

图 4–1 持久性数据存储库

该图显示了持久性服务使用基于平面文件的数据存储库,或使用基于 JDBC 的数据存储库。

基于文件的持久性

默认情况下,Message Queue 使用基于文件的持久性数据存储库,在这种存储库中使用单个文件来存储持久性数据,如消息、目的地、长期订阅和事务。 基于文件的持久性中列出了与基于文件的持久性相关的代理配置属性。

基于文件的存储库位于某个目录中,该目录使用数据存储库所属的代理实例的名称 (instanceName) 进行标识:

/instances/instanceName
/fs350/

(有关 instances 目录的位置,请参见附录 A, Message QueueTM 数据在特定平台上的位置。)代理中的每个目的地都有其自身的子目录,用于保存传送到该目的地的消息。


注 –

由于持久性数据存储库可能会包含敏感或专用的消息,因此应该保护 /instances/ instanceName/fs350/ 目录不受未经授权的访问;请参见保护持久性数据


消息以外的所有持久性数据都存储在单独的文件中:一个文件用于目的地,另一个文件用于长期订阅,第三个文件用于事务状态信息。 大多数消息都存储在由大小可变的记录组成的单个文件中。可以压缩此文件以减少添加和删除消息时产生的碎片(请参见压缩物理目的地)。此外,超过特定阈值大小的消息将存储在其各自的文件中,而不是存储在大小可变的记录文件中。可以使用代理属性 imq.persist.file.message.max_record_size 来配置此阈值的大小。

代理为这些单个的消息文件维护一个文件池:当不再需要某个文件时,并不会将其删除,而是重新放入目的地目录的空闲文件池中,以便日后其他消息可以重新使用该文件。 代理属性 imq.persist.file.destination.message.filepool.limit 指定池中的最大文件数。当某个目的地的单个消息文件数超过此限制时,将删除不再需要的文件,而不是将其重新放入文件池。

如果将文件重新放入文件池,则代理可以节省时间,但会占用存储器空间,因为它只是将文件标记为可重新使用,而没有删除文件以前的内容。 可以使用 imq.persist.file.message.filepool.cleanratio 代理属性来指定每个目的地的文件池中应保持“清除”(空)状态(而不是仅仅标记为可重新使用)的文件数百分比。 此值设置得越高,文件池所需的空间越少,但清空文件内容(当文件重新放入文件池时)所需的开销也越大。如果代理的 imq.persist.file.message.cleanup 属性为 true,则在代理关闭时将清空池中的所有文件,使其保持清除状态;这样可以节省存储器空间,但会减慢关闭过程。

将数据写入持久性存储库时,操作系统在以同步还是“延迟”(异步)方式写入数据方面存在一定的不准确性。 延迟存储可能会导致数据在系统崩溃时丢失(如果代理认为数据已经写入持久性存储库,但实际并未写入)。为了确保绝对的可靠性(以牺牲性能为代价),可以将代理属性 imq.persist.file.sync.enabled 设置为 true,以要求同步写入所有数据。 在这种情况下,当系统在崩溃后恢复运行时,可以保证数据是可用的,并且代理可以可靠地恢复运行。但请注意,虽然数据并未丢失,但却不能用于群集中的任何其他代理,因为群集中的代理当前并未共享该数据。

基于 JDBC 的持久性

可以不使用基于文件的持久性,而将代理设置为访问可通过 JDBC 驱动程序进行访问的任何数据存储库。 这需要设置适当的与 JDBC 相关的代理配置属性,以及使用数据库管理器实用程序 (imqdbmgr) 创建具有正确结构的数据库。有关详细信息,请参见配置基于 JDBC 的存储库

基于 JDBC 的持久性中列出了用于将代理配置为使用 JDBC 数据库的属性。可以在每个代理实例的实例配置文件 (config.properties ) 中指定这些属性,也可以使用代理实用程序 (imqbrokerd) 或数据库管理器实用程序 (imqdbmgr) 的 -D 命令行选项来指定这些属性。

imq.persist.jdbc.driver 属性提供了连接到数据库时使用的 JDBC 驱动程序的 Java 类名。 还有一些属性用于指定具有以下功能的 URL:连接到现有数据库 (imq.persist.jdbc.opendburl)、创建新的数据库 (imq.persist.jdbc.createdburl) 和关闭数据库连接 (imq.persist.jdbc.closedburl)。

imq.persist.jdbc.userimq.persist.jdbc.password 属性提供了用于访问数据库的用户名和密码;imq.persist.jdbc.needpassword 是用于指定是否需要密码的布尔标志。 为了安全起见,应该仅在通过 -passfile 命令行选项指定的密码文件中指定密码;如果未指定此类密码文件,则 imqbrokerdimqdbmgr 命令将以交互方式提示您指定密码。 同样,可以通过在命令行中使用 imqbrokerd 命令的 -dbuser 选项或 imqdbmgr 命令的 -u 选项来提供用户名。

在由多个代理实例共享的 JDBC 数据库中,配置属性 imq.persist.jdbc.brokerid 指定每个实例的唯一实例标识符,该标识符将被附加到数据库表名的后面。 (嵌入式数据库只存储一个代理实例的数据,因此通常不需要此属性。)与 JDBC 相关的其余配置属性用于自定义创建数据库结构的 SQL 代码,每个数据库表对应一个属性。 例如,imq.persist.jdbc.table.IMQSV35 属性提供用于创建版本表的 SQL 命令,imq.persist.jdbc.table.IMQCCREC35 属性提供用于创建配置更改记录表的 SQL 命令,imq.persist.jdbc.table.IMQDEST35 属性则提供用于创建目的地表的 SQL 命令,等等;有关完整列表,请参见表 14–6


注 –

由于各个数据库系统所要求的具体 SQL 语法不同,因此请务必查看数据库供应商提供的相应文档以了解详细信息。


安全服务

Message Queue 为用户访问控制(验证和授权)和加密提供了安全服务。

Message Queue 管理员负责设置代理在验证用户以及为用户授予操作权限时所需的信息。 安全属性中列出了与安全服务有关的代理属性。 布尔属性 imq.accesscontrol.enabled 充当一个主开关,用于控制是否在代理范围内应用访问控制;要进行更精细的控制,可以通过设置 imq.serviceName .accesscontrol.enabled 属性(其中,serviceName 是连接服务的名称,如表 4–1 所示)来覆盖特定连接服务的此设置:例如,imq.httpjms.accesscontrol.enabled

图 4–2 显示了代理在提供验证和授权服务时所需的组件。 这些服务依赖于用户系统信息库,该系统信息库包含有关消息传送系统用户的以下信息: 用户名、密码和组成员资格。此外,为了给用户或组授予执行特定操作的权限,代理还会查询访问控制属性文件,该文件指定了用户或组可以执行的操作。可以使用配置属性 imq.accesscontrol.file.filename 为整个代理指定一个访问控制属性文件,也可以使用 imq.serviceName. accesscontrol.file.filename 为单个连接服务指定访问控制属性文件。

图 4–2 安全支持

该图显示了代理的安全服务既使用用户系统信息库,又使用访问控制属性文件。

图 4–2 所示,您可以将用户数据存储在随 Message Queue 服务一起提供的平面文件用户系统信息库中,也可以将它们插入原有的轻量目录访问协议 (Lightweight Directory Access Protocol, LDAP) 系统信息库中:

代理的 imq.authentication.basic.user_repository 属性指定要使用的系统信息库的类型。通常,如果可伸缩性很重要,或者您需要让不同的代理共享系统信息库(例如,如果您使用的是代理群集),则最好使用 LDAP 系统信息库。有关设置平面文件或 LDAP 用户系统信息库的详细信息,请参见用户验证

验证

请求与代理建立连接的客户端必须提供用户名和密码,代理会将该用户名和密码与存储在用户系统信息库中的用户名和密码进行比较。从客户端传输到代理的密码是使用 Base-64 编码(对于平面文件系统信息库)或消息摘要 (MD5) 散列(对于 LDAP 系统信息库)进行编码的。 具体提供哪一种编码由 imq.authentication.type 属性(对于整个代理)或 imq.serviceName. authentication.type 属性(对于特定连接服务)控制。imq.authentication.client.response.timeout 属性设置验证请求的超时时间间隔。

密码文件中所述,您可以选择将密码放在密码文件中,而不是让系统以交互方式提示您指定密码。 此选项由布尔型代理属性 imq.passfile.enabled 控制。如果此属性为 true,则 imq.passfile.dirpathimq.passfile.name 属性提供密码文件的目录路径和文件名。 imq.imqcmd.password 属性(可以嵌入密码文件中)指定密码,该密码用于验证管理用户是否有权使用命令实用程序 (imqcmd) 来管理代理、连接服务、连接、物理目的地、长期订阅和事务。

如果您使用的是基于 LDAP 的用户系统信息库,则可以使用所有代理属性来配置 LDAP 查找的各个方面。LDAP 服务器自身的地址(主机名和端口号)由 imq.user_repository.ldap.server 指定。imq.user_repository.ldap.principal 属性提供用于绑定到 LDAP 系统信息库的标识名,而 imq.user_repository.ldap.password 则提供关联的密码。其他属性为单个的用户和组搜索指定目录库和可选 JNDI 过滤器,为用户和组名指定特定于提供者的属性标识符,等等;有关详细信息,请参见安全属性

授权

用户通过验证后,即可被授权执行与 Message Queue 相关的各种活动。 Message Queue 管理员可以定义用户组,并指定组中各个用户的成员资格。 默认的访问控制属性文件只明确地引用一个组,即 admin(请参见 )。此组中的用户具有 admin 连接服务的连接权限, 该权限允许用户执行诸如创建目的地以及监视和控制代理等管理功能。 默认情况下,您定义的任何其他组中的用户都无法获取 admin 服务连接。

当用户尝试执行某个操作时,代理将对照访问控制属性文件中指定的允许执行该操作的用户名和组成员资格,来检查用户系统信息库中该用户的用户名和组成员资格。 访问控制属性文件为用户或组指定了执行以下操作的权限:

加密

要对客户端与代理之间发送的消息进行加密,需要使用基于安全套接字层 (Secure Socket Layer, SSL) 标准的连接服务。 SSL 通过在启用 SSL 的代理与客户端之间建立加密连接来提供连接级别的安全性。

要使用基于 SSL 的 Message Queue 连接服务,需要使用密钥工具实用程序 (imqkeytool) 生成公钥/私钥对。此实用程序将公钥嵌入自签名的证书中,然后将此证书放入 Message Queue 密钥库中。 密钥库自身受密码保护;要解除对密钥库的锁定,必须在启动时提供由 imq.keystore.password 属性指定的密钥库密码。 解除对密钥库的锁定后,代理即可将证书传递给请求连接的任何客户端。然后,客户端可以使用此证书建立与代理的加密连接。

imq.audit.enabled 代理属性控制将审计记录记录到 Message Queue 代理日志文件的行为;有关详细信息,请参见审计日志记录

监视服务

代理中包含一些用于监视和诊断应用程序及代理性能的组件。其中包括:

图 4–3 中显示的是常规模式。 监视属性中列出了用于配置监视服务的代理属性。

图 4–3 监视支持

该图显示了记录程序的输入、错误级别以及输出通道。图采用文本进行说明。

度量生成器

度量生成器提供有关代理活动的信息,如流入流出代理的消息、代理内存中的消息数及其使用的内存量、打开的连接数以及正在使用的线程数。 布尔型代理属性 imq.metrics.enabled 控制是否记录此类信息;imq.metrics.interval 指定记录的频率。

记录程序

出错时,记录程序获取代理代码和度量生成器生成的信息,并将这些信息写入标准输出(控制台)、日志文件以及 syslog 守护进程(在 Solaris 平台上)中。要使用的日志文件由 imq.log.file.dirpathimq.log.file.filename 代理属性标识; imq.log.console.stream 指定将控制台输出定向到 stdout 还是 stderr

imq.log.level 属性控制记录程序收集的度量信息的类别: ERRORWARNINGINFO。每个级别都包括高于它的级别,因此,如果您指定 WARNING 作为日志记录级别,则将同时记录错误消息。imq.log.console.outputimq.log.file.output 属性分别控制将哪些指定类别写入控制台和日志文件。 但在这种情况下,类别并不包括高于它的类别;因此,如果您要将错误和警告写入日志文件,而将信息性消息写入控制台,则必须明确地将 imq.log.file.output 设置为 ERROR|WARNING,将 imq.log.console.output 设置为 INFO。在 Solaris 平台上,使用另一个属性 imq.log.syslog.output 来指定要写入 syslog 守护进程的度量信息的类别。 此外还有一个 imq.destination.logDeadMsgs 属性,该属性指定当停用消息被丢弃或移动到停用消息队列时是否进行记录。

对于日志文件,可以指定何时关闭文件并将输出转移到新文件。 当日志文件达到指定的大小 (imq.log.file.rolloverbytes) 或生存期 (imq.log.file.rolloversecs) 之后,将保存该文件并创建一个新的日志文件。

有关与日志记录相关的其他代理属性,请参见监视属性;有关如何配置记录程序以及如何使用它来获取性能信息的更多详细信息,请参见配置和使用代理日志记录

度量消息生成方 (Enterprise Edition)

度量消息生成方以一定的时间间隔从度量生成器接收信息,并将该信息写入度量消息,然后根据消息中包含的度量信息类型,将度量消息发送到多个度量主题目的地之一(请参见表 4–2)。订阅这些度量主题目的地的 Message Queue 客户端可以使用这些消息并处理消息中包含的度量数据。 这样,开发者就可以创建自定义监视工具来支持消息传送应用程序。有关在每种类型的度量消息中报告的度量数量的详细信息,请参见 Message Queue Developer's Guide for Java Clients

表 4–2 度量主题目的地

主题名称 

度量信息类型

mq.metrics.broker

代理度量 

mq.metrics.jvm

Java 虚拟机度量 

mq.metrics.destination_list

目的地及其类型的列表 

mq.metrics.destination.queue.queueName

指定队列的目的地度量 

mq.metrics.destination.topic.topicName

指定主题的目的地度量 

代理属性 imq.metrics.topic.enabledimq.metrics.topic.interval 分别控制是否将消息发送到度量主题目的地以及发送的频率。 imq.metrics.topic.timetoliveimq.metrics.topic.persist 属性分别指定此类消息的生命周期和持久性。

除了包含在度量消息主体中的信息之外,每个消息头中还包含提供以下附加信息的属性:

这些属性对于处理不同类型(或来自不同代理)度量消息的客户端应用程序非常有用。

设置代理属性

可以通过以下两种方式之一来指定代理的配置属性:

以下两节介绍了这两种配置代理的方法。

配置文件

代理配置文件包含用于配置代理的属性设置。 这些文件保存在一个目录中,该目录的位置取决于使用的操作系统平台;有关详细信息,请参见附录 A, Message QueueTM 数据在特定平台上的位置。该目录存储以下文件:

此外,每个单独的代理实例都有其自身的实例配置文件,如下所述。如果连接群集中的代理实例,您可能还需要使用群集配置文件来指定群集的配置信息;有关详细信息,请参见群集配置属性

启动时,代理会合并各个配置文件中的属性值。 如图 4–4 中所示,这些文件构成了一个分层结构,在此结构中,实例配置文件中指定的值将覆盖安装配置文件中的值,而安装配置文件中的值又将覆盖默认配置文件中的值。 在分层结构的顶部,您可以通过使用 imqbrokerd 命令的命令行选项来手动覆盖配置文件中指定的任何属性值。

图 4–4 代理配置文件

该图显示了出命令行选项优先于 config.properties 选项,config.properties 选项优先于 install.properties 选项, install.properties 选项优先于默认选项。

编辑实例配置文件

首次运行代理时,将创建一个实例配置文件,其中包含该特定代理实例的配置属性。该实例配置文件被命名为 config.properties,并存储在由所属代理实例的名称标识的目录中:

/instances/ instanceName/props/config.properties

(有关 instances 目录的位置,请参见附录 A, Message QueueTM 数据在特定平台上的位置。)如果该文件不存在,则必须在启动代理时使用 -name 选项(请参见代理实用程序)指定一个实例名, Message Queue 可以使用该实例名来创建文件。


注 –

instances/instanceName 目录和实例配置文件由创建相应代理实例的用户所有。 代理实例必须始终由该用户重新启动。


实例配置文件由代理实例维护,并在您使用 Message Queue 管理实用程序更改配置时进行相应的更改。 您也可以手动编辑实例配置文件,以便自定义代理的行为和资源使用。 要执行此操作,您必须是 instances/instanceName 目录的拥有者,或者以 root 身份登录,以更改目录的访问权限。

代理仅在启动时读取实例配置文件。要对代理配置进行永久性更改,您必须关闭代理,编辑该文件,然后重新启动代理。 该文件(或任何配置文件)中的属性定义使用以下语法:

propertyName=value [[,value1] ]

例如,下面的条目指定,代理最多可以在内存和持久性存储库中保存 50, 000 条消息,超过此限制后,将拒绝其他消息:

imq.system.max_count=50000

下面的条目指定,将每天(86, 400 秒)创建一个新的日志文件:

imq.log.file.rolloversecs=86400

有关可用代理配置属性及其默认值的信息,请参见代理服务第 14 章,代理属性参考

从命令行设置配置选项

在启动代理时(或之后),可以在命令行中输入代理配置选项。

在启动时,可使用代理实用程序 (imqbrokerd) 启动代理实例。 通过使用该命令的 -D 选项,可以指定任何代理配置属性及其值;有关详细信息,请参见启动代理代理实用程序。如果使用服务管理器实用程序 ( imqsvcadmin) 将代理作为 Windows 服务启动,则可使用 -args 选项指定启动配置属性;请参见服务管理器实用程序

在代理实例运行时,还可以更改某些代理属性。 要修改正在运行的代理的配置,请使用命令实用程序的 imqcmd update bkr 命令;请参见更新代理属性代理管理

配置持久性数据存储库

代理的持久性数据存储库保存有关物理目的地、长期订阅、消息、事务和确认的信息。默认情况下,Message Queue 代理被配置为使用基于文件的持久性存储库,但您可以将其重新配置为插入可通过 JDBC 驱动程序访问的任何数据存储库。代理配置属性 imq.persist.store(见表 14–4)指定使用两种持久性形式中的哪一种。

本节介绍了如何设置代理以使用持久性存储库。包括以下主题:

配置基于文件的存储库

在创建代理实例时,将自动创建基于文件的数据存储库。存储库位于代理的实例目录中;有关确切位置,请参见附录 A, Message QueueTM 数据在特定平台上的位置

默认情况下,Message Queue 执行异步的磁盘写入操作。操作系统可以缓冲这些操作以获取高性能。但是,如果在两次写入操作之间出现意外的系统故障,则消息可能会丢失。为了提高可靠性(但会降低性能),可以设置代理属性 imq.persist.file.sync 以改为同步写入数据。 有关此属性的进一步论述,请参见基于文件的持久性表 14–5

启动代理实例时,可以使用 imqbrokerd 命令的 -reset 选项清除文件系统存储库。 有关此选项及其子选项的详细信息,请参见代理实用程序

配置基于 JDBC 的存储库

要配置代理以使用基于 JDBC 的持久性,请在代理的实例配置文件中设置与 JDBC 相关的属性,并创建相应的数据库结构。 Message Queue 数据库管理器实用程序 ( imqdbmgr) 使用 JDBC 驱动程序和代理配置属性来创建和管理数据库。如果数据库表已经损坏或者您希望使用其他的数据库作为数据存储库,则还可以使用数据库管理器从数据库中删除损坏的表或删除数据库。 有关详细信息,请参见数据库管理器实用程序


注 –

系统提供了 Oracle 和 PointBase 数据库产品的示例配置。这些文件的位置因平台而异,在附录 A, Message QueueTM 数据在特定平台上的位置 中相关表的“示例应用程序和配置”下列出了此位置。此外,在实例配置文件 config.properties 中以注释值的形式提供了 PointBase 嵌入式版本、PointBase 服务器版本和 Oracle 的示例。


Procedure配置基于 JDBC 的数据存储库

  1. 在代理的配置文件中设置与 JDBC 相关的属性。

    基于 JDBC 的持久性中讨论了这些相关属性,并在表 14–6 中列出了这些属性。需要特别指出的是,您必须将代理的 imq.persist.store 属性设置为 jdbc(请参见持久性属性)。

  2. 将 JDBC 驱动程序的 .jar 文件的副本或符号链接放入以下位置:

    • 在 Solaris 上:


      /usr/share/lib/imq/ext/
    • 在 Linux 上:


      /opt/sun/mq/share/lib/
    • 在 Windows 上:


      IMQ_VARHOME\\lib\\ext

    例如,如果您在 Solaris 系统上使用 PointBase,则以下命令将驱动程序的 .jar 文件复制到相应位置:


    % cp j2eeSDKInstallDirectory/pointbase/lib/pointbase.jar /usr/share/lib/imq/ext

    以下命令则创建一个符号链接:


    % ln -s j2eeSDKID/lib/pointbase/pointbase.jar /usr/share/lib/imq/ext
  3. 创建 Message Queue 持久性所需的数据库结构。

    使用 imqdbmgr create all 命令(对于嵌入式数据库)或 imqdbmgr create tbl 命令(对于外部数据库);请参见数据库管理器实用程序

    1. 转到 imqdbmgr 所在的目录:

      • 在 Solaris 上:


        cd /usr/bin
      • 在 Linux 上:


        cd /opt/sun/mq/bin
      • 在 Windows 上:


        cd IMQ_HOME\\bin
    2. 输入 imqdbmgr 命令:

      imqdbmgr create all


      注 –

      如果使用嵌入式数据库,则最好在以下目录中创建它:

      /instances/ instanceName/dbstore/ databaseName

      如果嵌入式数据库未设置用户名和密码保护,则可能设置了文件系统权限保护。要确保代理能够对数据库进行读写访问,则运行该代理的用户应该是使用 imqdbmgr 命令创建该嵌入式数据库的用户。


保护持久性数据

持久性存储库可以包含临时存储的消息文件以及其他信息。 由于这些消息可能包含专用信息,因此保护数据存储库以防止未经授权的访问非常重要。本节介绍了如何保护基于文件或基于 JDBC 的数据存储库中的数据。

保护基于文件的存储库

使用基于文件持久性的代理将持久性数据写入平面文件数据存储库,该数据存储库的位置因平台而异(请参见附录 A, Message QueueTM 数据在特定平台上的位置):

/instances/ instanceName/fs350/

其中 instanceName 是标识代理实例的名称。

instanceName/fs350/ 目录是在第一次启动代理实例时创建的。保护此目录的过程取决于运行代理的操作系统平台:

保护基于 JDBC 的存储库

使用基于 JDBC 持久性的代理将持久性数据写入符合 JDBC 的数据库。对于由数据库服务器管理的数据库(如 Oracle), 建议创建一个用户名和密码来访问 Message Queue 数据库表(名称以 IMQ 开头的表)。如果数据库不允许保护单个表,请创建一个仅由 Message Queue 代理使用的专用数据库。请参见数据库供应商提供的文档,以了解有关如何创建用户名/密码访问的信息。

代理打开数据库连接所需的用户名和密码可以作为代理配置属性来提供。但是,一种更安全的方法是在启动代理时将它们作为命令行选项(使用 imqbrokerd 命令的 -dbuser -dbpassword 选项)提供(请参见代理实用程序)。

对于代理通过数据库 JDBC 驱动程序直接访问的嵌入式数据库,通常通过在要存储持久性数据的目录上设置文件权限来提供安全性,如前面的保护基于文件的存储库中所述。但是,要确保代理和数据库管理器实用程序均可读写数据库,二者应该由同一个用户来运行。

第 5 章 管理代理

本章介绍如何使用 imqcmd 实用程序来管理代理及其服务。本章包括以下各节:

本章并未涵盖与管理代理相关的全部主题。其他主题将在后面的各章中进行介绍:

前提条件

使用 imqcmdimqusermgr 命令行实用程序来管理代理。 在管理代理前,必须执行以下操作:

使用 imqcmd 实用程序

imqcmd 实用程序用于管理代理及其服务。

有关 imqcmd 命令的语法、子命令和选项的参考信息,请参见第 13 章,命令行参考。在单独的第 15 章,物理目的地属性参考中,介绍了管理物理目的地时可使用的参考信息。

显示帮助

要显示有关 imqcmd 实用程序的帮助,请使用 -h-H 选项,而不要使用子命令。您无法获取有关特定子命令的帮助。

例如,以下命令显示有关 imqcmd 的帮助:

imqcmd -H

如果输入的命令行除了包含 -h -H 选项外,还包含子命令或其他选项,则 imqcmd 实用程序只处理 -h-H 选项。命令行中的其他所有项均被忽略。

显示产品版本

要显示 Message Queue 产品版本,请使用 -v 选项。例如:

imqcmd -v

如果输入的命令行除了包含 -v 选项外,还包含子命令或其他选项,则 imqcmd 实用程序只处理 -v 选项。命令行中的其他所有项均被忽略。

指定用户名和密码

因为将对照用户系统信息库验证每个 imqcmd 子命令,所以每个子命令都要求提供用户名和密码。唯一的例外是使用 -h 或 -H 选项来显示帮助的命令以及使用 -v 选项来显示产品版本的命令。

指定用户名

使用 -u 选项可指定管理用户名。如果省略了用户名,该命令会提示您输入它。例如,以下命令显示有关默认代理的信息:

imqcmd query bkr -u admin

为使本章中的示例便于阅读,我们将默认用户名 admin 显示为 -u 选项的参数。在生产环境中,应该使用自定义的用户名。

指定密码

使用以下方法之一指定密码:

在 Message Queue 的以前版本中,可以使用 -p 选项在 imqcmd 命令行中指定密码。不赞成使用此选项,在今后的版本中会将其删除。

指定代理名和端口

imqcmd 的默认代理是本地主机上运行的代理,默认端口是 7676

如果对在远程主机上运行的代理或监听非默认端口的代理执行命令,则必须使用 -b 选项指定代理的主机和端口。

示例

本节中的示例说明了 imqcmd 的用法。

第一个示例列出了在 localhost 端口 7676 上运行的代理的属性,因此不需要使用 -b 选项。该命令使用默认管理用户名 (admin ) 并省略了密码,因此命令会提示您输入密码。

imqcmd query bkr -u admin

以下示例列出了在主机 myserver 端口 1564 上运行的代理的属性。用户名是 aladdin。(要使该命令起作用,需要更新用户系统信息库,将用户名 aladdin 添加到 admin 组中。)

imqcmd query bkr -b myserver:1564 -u aladdin

以下示例列出了在 localhost 端口 7676 上运行的代理的属性。命令的初始超时时间限制设置为 20 秒,超时后的重试次数设置为 7。用户密码在名为 myPassfile 的密码文件中,该文件位于调用命令时的当前目录中。

imqcmd query bkr -u admin -passfile myPassfile -rtm 20 -rtr 7

对于安全的代理连接,这些示例可能会包括 -secure 选项。-secure 选项使 imqcmd 使用 ssladmin 服务(如果已配置并启动了该服务)。

显示代理信息

要查询并显示某个代理的信息,请使用 query bkr 子命令。

下面是 query bkr 子命令的语法:

imqcmd query bkr -b hostName:
portNumber

该子命令列出默认代理或指定主机和端口上的代理的当前属性设置。它还列出与指定代理连接且正在运行的代理(在多代理群集中)。

例如:

imqcmd query bkr -u admin

提示输入密码后,此命令将产生类似如下内容的输出:


Version                                              3.6
Instance Name                                        imqbroker
Primary Port                                         7676
                                                   
Current Number of Messages in System                 0
Current Total Message Bytes in System                0

Current Number of Messages in Dead Message Queue     0
Current Total Message Bytes in Dead Message Queue    0

Log Dead Messages                                    true
Truncate Message Body in Dead Message Queue          false
                                                   
Max Number of Messages in System                     unlimited (-1)
Max Total Message Bytes in System                    unlimited (-1)
Max Message Size                                     70m
                                                   
Auto Create Queues                                   true
Auto Create Topics                                   true
Auto Created Queue Max Number of Active Consumers    1
Auto Created Queue Max Number of Backup Consumers    0
                                                   
Cluster Broker List (active)                         
Cluster Broker List (configured)                     
Cluster Master Broker                                
Cluster URL                                          
                                                   
Log Level                                            INFO
Log Rollover Interval (seconds)                      604800
Log Rollover Size (bytes)                            unlimited (-1)

更新代理属性

可以使用 update bkr 子命令更新以下代理属性:

下面是 update bkr 子命令的语法:

imqcmd update bkr [-b hostName:
portNumb er]-o attribute=value
 [[-o attribute=value1]
]

该子命令更改默认代理或指定主机和端口上的代理的指定属性。例如,以下命令禁止自动创建队列目的地:

imqcmd update bkr -o "imq.autocreate.queue=false" -u admin

这些属性在第 14 章,代理属性参考中介绍。

暂停和恢复代理

启动代理后,可以使用 imqcmd 子命令控制代理的状态。

暂停代理

暂停代理时暂停的是代理的连接服务线程,从而使代理停止侦听连接端口。其结果是代理将无法再接受新连接、接收消息或分发消息。

但是,暂停代理不会暂停 admin 连接服务,因此您可以执行相应的管理任务,以控制发送到代理的消息流。暂停代理也不会暂停 cluster 连接服务。但是,群集中的消息传送依赖于群集中的不同代理所执行的传送功能。因此,暂停群集中的代理可能导致某些消息流的速度变慢。

下面是 pause bkr 子命令的语法:

imqcmd pause bkr [-b hostName:
portNumber]

此命令暂停默认代理或指定主机和端口上的代理。

以下命令暂停在 myhost 端口 1588 上运行的代理。

imqcmd pause bkr -b myhost:1588 -u admin

也可以暂停单个连接服务和单个物理目的地。有关详细信息,请参见暂停和恢复连接服务暂停和恢复物理目的地

恢复代理

恢复代理将重新激活代理的服务线程,使代理恢复侦听端口。

下面是 resume bkr 子命令的语法:

imqcmd resume bkr [-b hostName:
portNumber]

此子命令恢复默认代理或指定主机和端口上的代理。

以下命令将恢复在 localhost 端口 7676 上运行的代理。

imqcmd resume bkr -u admin

关闭并重新启动代理

关闭代理将正常终止代理进程。代理将停止接受新的连接和消息,并在完成现有消息的传送后终止代理进程。

下面是 shutdown bkr 子命令的语法:

imqcmd shutdown bkr [-b hostName:
portNumber]

此子命令关闭默认代理或指定主机和端口上的代理。

以下命令将关闭在 ctrlsrv 端口 1572 上运行的代理:

imqcmd shutdown bkr -b ctrlsrv:1572 -u admin

使用 restart bkr 子命令可关闭并重新启动代理。下面是 restart bkr 子命令的语法:

imqcmd restart bkr [-b hostName:
portNumber]

该子命令关闭并重新启动默认代理或指定主机和端口上的代理,重新启动时使用首次启动代理时指定的选项。 要选择其他选项,请关闭代理,然后通过指定所需的选项来重新启动它。

显示代理度量

要显示有关代理的度量信息,请使用 metrics bkr 子命令。

下面是 metrics bkr 子命令的语法:

imqcmd metrics bkr [-b hostName:
portNumber]
       [-m metricType] [-int interval] [-msp 
numSamples]

此子命令显示默认代理或指定主机和端口上的代理的代理度量。

可以使用 -m 选项来指定显示以下度量类型之一:

可以使用 -int 选项来指定显示度量的时间间隔(以秒为单位)。默认值为 5 秒。

可以使用 -msp 选项来指定在输出中显示的样例的数量。默认为无限制(无穷多)。

例如,要获得消息在 10 秒间隔内流入和流出代理的速率,请使用以下命令:

imqcmd metrics bkr -m rts -int 10 -u admin

此命令产生的输出如下:


--------------------------------------------------------
 Msgs/sec   Msg Bytes/sec   Pkts/sec    Pkt Bytes/sec   
 In   Out     In      Out     In   Out     In      Out  
--------------------------------------------------------
 0     0      27      56      0     0      38      66   
 10    0     7365     56      10    10    7457    1132  
 0     0      27      56      0     0      38      73   
 0     10     27     7402     10    20    1400    8459  
 0     0      27      56      0     0      38      73

有关代理所收集的和报告的数据的更详细描述,请参见代理范围内的度量

管理连接服务

imqcmd 实用程序包含可用于执行以下连接服务管理任务的子命令:

代理既支持来自应用程序客户端的连接 ,也支持来自管理客户端的连接。表 5–1 显示了 Message Queue 代理中当前可用的连接服务。 如该表所示,每项服务都与它所使用的服务类型(对于应用程序客户端是 NORMAL ,对于管理客户端是 ADMIN)和底层传输协议关联。

表 5–1 Message Queue 连接服务

服务名称 

服务类型 

协议类型

jms

NORMAL

TCP

ssljms (Enterprise Edition)

NORMAL

TLS(基于 SSL 的安全性)

httpjms (Enterprise Edition)

NORMAL

HTTP

httpsjms (Enterprise Edition)

NORMAL

HTTPS(基于 SSL 的安全性)

admin

ADMIN

TCP 

ssladmin (Enterprise Edition)

ADMIN

TLS(基于 SSL 的安全性) 

您可以使用 imqcmd 子命令将连接服务作为一个整体进行管理,也可以管理某项特定的连接服务。如果子命令的目标是某项特定的服务,请使用 -n 选项指定表 5–1 的“服务名称”列中列出的某个名称。

列出连接服务

要列出代理中可用的连接服务,请使用 list svc 子命令。

下面是 list svc 子命令的语法:

imqcmd list svc [-b hostName:
portNumber]

此子命令列出默认代理或指定主机和端口上的代理中的所有连接服务。

以下命令列出在 localhost 端口 7676 上运行的代理中的所有服务:

imqcmd list svc -u admin

该命令将输出如下信息:


------------------------------------------------
Service Name    Port Number        Service State
------------------------------------------------
admin           41844 (dynamic)    RUNNING
httpjms         -                  UNKNOWN
httpsjms        -                  UNKNOWN
jms             41843 (dynamic)    RUNNING
ssladmin        dynamic            UNKNOWN
ssljms          dynamic            UNKNOWN

显示连接服务信息

要查询并显示某项服务的信息,请使用 query 子命令。

下面是 query svc 子命令的语法:

imqcmd query svc -n serviceName [-b 
hostName:portNumber]

query svc 子命令显示在默认代理或指定主机和端口上的代理中运行的指定服务的相关信息。

例如:

imqcmd query svc -n jms -u admin

提示输入密码后,此命令将产生类似如下内容的输出:


Service Name                           jms
Service State                          RUNNING
Port Number                            60920 (dynamic)
                                     
Current Number of Allocated Threads    0
Current Number of Connections          0
                                     
Min Number of Threads                  10
Max Number of Threads                  1000

更新连接服务属性

可以使用 update 子命令更改表 5–2 中列出的一个或多个服务属性的值。

表 5–2 imqcmd 更新的连接服务属性

属性 

描述 

port

为要更新的服务指定的端口(不适用于 httpjms 或 httpsjms)。值为 0 表示端口由端口映射器动态分配。

minThreads

至少应分配给服务的线程数。

maxThreads

最多可分配给服务的线程数。 

下面是 update 子命令的语法:

imqcmd update svc -n serviceName [-b 
hostName:portNumber] 
         -o attribute=value [-o 
attribute=value1]

该子命令更新在默认代理或指定主机和端口上的代理中运行的指定服务的指定属性。有关服务属性的说明,请参见连接属性

以下命令将至少应分配给 jms 服务的线程数更改为 20。

imqcmd update svc -n jms -o “minThreads=20” -u admin

显示连接服务度量

要显示有关某个服务的度量信息,请使用 metrics 子命令。

下面是 metrics 子命令的语法:

imqcmd metrics svc -n serviceName [-b 
hostName:portNumber] [-m metricType
]
     [-int interval] [-msp numSamples]

此子命令显示默认代理或指定主机和端口上的代理中指定服务的度量。

使用 -m 选项指定要显示的度量类型:

可以使用 -int 选项来指定显示度量的时间间隔(以秒为单位)。默认值为 5 秒。

可以使用 -msp 选项来指定在输出中显示的样例的数量。默认为无限制(无穷多)。

例如,要获得 jms 连接服务处理的消息和包的累计总数,请使用以下命令:

imqcmd metrics svc -n jms -m ttl -u admin

提示输入密码后,此命令将产生类似如下内容的输出:


-------------------------------------------------
  Msgs      Msg Bytes      Pkts      Pkt Bytes   
In   Out    In     Out   In   Out    In     Out  
-------------------------------------------------
164  100  120704  73600  282  383  135967  102127
657  100  483552  73600  775  876  498815  149948

有关使用 imqcmd 来报告连接服务度量的详细说明,请参见连接服务度量

暂停和恢复连接服务

要暂停除管理服务之外的其他任何服务(不能暂停管理服务),请使用 pause svcresume svc 子命令。

下面是 pause svc 子命令的语法:

imqcmd pause svc -n serviceName [-b 
hostName:portNumber]

此子命令暂停在默认代理或指定主机和端口上的代理中运行的指定服务。例如,以下命令暂停在默认代理上运行的 httpjms 服务。

imqcmd pause svc -n httpjms -u admin

暂停服务有如下影响:

要恢复服务,请使用 resume svc 子命令。

下面是 resume svc 子命令的语法:

imqcmd resume svc -n serviceName[-b 
hostName:portNumber]

此子命令恢复在默认代理或指定主机和端口上的代理中运行的指定服务。

获取有关连接的信息

imqcmd 实用程序包含可用来列出并获取连接信息的子命令。

list cxn 子命令列出指定服务名的全部连接。下面是 list cxn 子命令的语法:

imqcmd list cxn [-svn serviceName] [-b 
hostName:portNumber]

此子命令列出默认代理或指定主机和端口上的代理中指定服务名的所有连接。 如果未指定服务名,将列出所有连接。

例如,以下命令列出默认代理上的所有连接:

imqcmd list cxn -u admin

提示输入密码后,此命令将产生类似如下内容的输出:


Listing all the connections on the broker specified by:
-----------------------------------
Host                   Primary Port
------------------------------------
localhost              7676

---------------------------------------------------------------------------
Connection ID         User    Service   Producers  Consumers    Host
---------------------------------------------------------------------------
1964412264455443200   guest   jms       0          1            127.0.0.1
1964412264493829311   admin   admin     1          1            127.0.0.1

Successfully listed connections.

要查询并显示某项连接服务的信息,请使用 query 子命令。

query cxn -n connectionID [-b 
hostName:portNumber]

此子命令显示默认代理或指定主机和端口上的代理中的指定连接的信息。

例如:

imqcmd query cxn -n 421085509902214374 -u admin

提示输入密码后,此命令将产生类似如下内容的输出:


Connection ID      421085509902214374
User               guest
Service            jms
Producers          0
Consumers          1
Host               111.22.333.444
Port               60953
Client ID          
Client Platform    

管理长期订阅

使用 imqcmd 子命令,可以通过执行下面一项或多项操作来管理代理的长期订阅:

长期订阅是指客户端注册为长期项的主题订阅;长期订阅有唯一标识,它要求代理保留该订阅的消息,即使订阅使用方变为非活动状态也是如此。 通常情况下,代理只能在消息已过期的情况下删除为长期订户保留的消息。

要列出指定物理目的地的长期订阅,请使用 list dur 子命令。下面是 list dur 子命令的语法:

imqcmd list dur -d destName

例如,以下命令使用本地主机的默认端口上的代理,列出 SPQuotes 主题的所有长期订阅:

imqcmd list dur -d SPQuotes

对于主题的每个长期订阅,list dur 子命令都返回长期订阅的名称、用户的客户端 ID、排队发往该主题的消息数量以及长期订阅的状态(活动/非活动)。例如:


Name        Client ID       Number of   Durable Sub
                            Messages      State
----------------------------------------------------------------
myDurable   myClientID       1           INACTIVE

可以使用 list dur 子命令返回的信息标识您要销毁或要清除其消息的长期订阅。

purge dur 子命令清除带有指定客户端标识符的指定长期订阅的所有消息。下面是 purge dur 子命令的语法:

imqcmd purge dur -n subscrName -c 
clientID

destroy dur 子命令销毁带有指定客户端标识符的指定长期订阅。下面是 destroy dur 子命令的语法:

imqcmd destroy dur -n subscrName -c 
clientID

例如,以下命令销毁长期订阅 myDurable 和客户端 ID myClientID

imqcmd destroy dur -n myDurable -c myClientID

管理事务

客户端应用程序启动的所有事务都由代理来跟踪。这些事务可以是简单 Message Queue 事务,也可以是分布式事务(XA 资源)管理器管理的分布式事务。

每个事务都有一个 Message Queue 事务 ID:这是一个 64 位数字,用于唯一标识代理上的事务。分布式事务也有一个分布式事务 ID (XID),长度可达 128 字节,由分布式事务管理器指定。Message Queue 负责维护 Message Queue 事务 ID 与 XID 之间的关联。

对于分布式事务而言,当失败时,事务可能停留在 PREPARED 状态,而不会提交。因此,作为管理员,您需要监视事务的状态,并回滚或提交那些停留在 PREPARED 状态的事务。

要列出代理跟踪的所有事务,请使用 list txn 命令。下面是 list txn 子命令的语法:

imqcmd list txn

例如,以下命令列出某个代理中的所有事务。

imqcmd list txn

对于每个事务,list 子命令将返回事务 ID、状态、用户名、消息数或确认数以及创建时间。例如:


---------------------------------------------------------------
Transaction ID  State    User name   # Msgs/   Creation time
                                     # Acks
---------------------------------------------------------------

64248349708800  PREPARED  guest      4/0      1/30/02 10:08:31 AM
64248371287808  PREPARED  guest      0/4      1/30/02 10:09:55 AM

该命令显示了代理中的所有事务,包括本地事务和分布式事务。只能提交或回滚处于 PREPARED 状态的事务。只有当您知道该事务由于失败而停留在 PREPARED 状态,而且分布式事务管理器当前没有提交该事务时才可以这样做。

例如,如果代理的 auto-rollback 属性设置为 false(请参见表 14–2),则必须在代理启动时手动提交或回滚处于 PREPARED 状态的事务。

list 子命令还分别显示事务中生成和确认的消息数 (#Msgs/#Acks)。提交事务之前不会传送这些消息,也不会处理确认。

query 子命令可以显示上述信息以及其他许多值:客户端 ID、连接标识和分布式事务 ID (XID)。下面是 query txn 子命令的语法:

imqcmd query txn -n transactionID

例如,以下示例生成如下所示的输出:

imqcmd query txn -n 64248349708800

Client ID
Connection                 guest@192.18.116.219:62209->jms:62195
Creation time              1/30/02 10:08:31 AM
Number of acknowledgments 0
Number of messages         4
State                      PREPARED
Transaction ID             64248349708800
User name                  guest
XID
6469706F6C7369646577696E6465723130313234313431313030373230

使用 commitrollback 子命令可以提交和回滚分布式事务。正如前文所述,只能提交和回滚处于 PREPARED 状态的事务。

下面是 commit 子命令的语法:

imqcmd commit txn -n transactionID

例如:

imqcmd commit txn -n 64248349708800

下面是 rollback 子命令的语法。子命令:

imqcmd rollback txn -n transactionID

有关详细信息,请参见表 14–2 中的 imq.transaction.autorollback 属性。

也可以配置代理,使它在启动时自动回滚处于 PREPARED 状态的事务。

第 6 章 管理物理目的地

本章介绍如何使用 imqcmd 实用程序管理物理目的地。Message QueueTM 消息通过代理上的物理目的地路由到使用方客户端。代理管理与物理目的地关联的内存和持久性存储库并设置它们的行为。

在代理群集中,您在某个代理上创建一个物理目的地后,群集会将该物理目的地传播给所有其他代理。应用程序客户端可以订阅某一主题,或者使用群集中任何代理上的队列,因为这些代理会协同工作,在整个群集中路由消息。但是,该消息的持久性和确认只由最初生成消息的代理负责管理。

本章包含以下主题:

表 13–5 中提供了用于管理物理目的地和完成上述任务的 imqcmd 子命令的完整参考信息。

有关物理目的地的介绍,请参见 Message Queue 技术概述


注 –

每当与物理目的地交互时,客户端应用程序都会使用目的地对象。为了实现提供者无关性和可移植性,客户端通常使用管理员创建的目的地对象,这些对象称为目的地受管理对象。可以配置受管理对象,使其可供客户端应用程序使用,如第 8 章,管理受管理对象中所述。


使用命令实用程序

可以使用 Message Queue 命令实用程序 (imqcmd) 来管理物理目的地。 imqcmd 命令的语法与管理其他代理服务时的语法一样。

有关 imqcmd 及其子命令和选项的完整参考信息,请参见第 13 章,命令行参考

子命令

表 6–1 列出了 imqcmd 子命令,本章介绍了这些子命令的用法。 有关这些子命令的参考信息,请参见物理目的地管理

表 6–1 命令实用程序的物理目的地子命令

子命令和参数 

描述 

compact dst

压缩一个或多个物理目的地的基于文件的数据存储库。 

create dst

创建物理目的地。 

destroy dst

销毁物理目的地。 

list dst

列出代理中的物理目的地。 

metrics dst

显示物理目的地度量。 

pause dst

暂停代理中的一个或多个物理目的地。 

purge dst

清除物理目的地中的所有消息,但不销毁该物理目的地。 

query dst

查询并显示有关物理目的地的信息。 

resume dst

恢复代理中的一个或多个暂停的物理目的地。 

update dst

更新目的地属性。 

创建物理目的地

要创建物理目的地,请使用 imqcmd create 子命令。 下面是 create 子命令的语法:

create dst -t destType -n 
destName [-o property=value
] [-o property=value1]

例如,要创建队列目的地,请输入以下命令:


imqcmd create dst -n myQueue -t q -o "maxNumActiveConsumers=5"

要创建主题目的地,请输入以下命令:


imqcmd create dst -n myTopic -t t -o "maxBytesPerMsg=5000"

创建物理目的地时,请指定以下内容:

也可以在更新物理目的地时设置属性。

许多物理目的地属性都影响代理的内存资源和消息流。例如,可以指定能发送到物理目的地的生成方数量,它们可以发送的消息数量和大小,以及达到物理目的地限制时代理应做出的响应。这些限制与由代理配置属性控制的代理范围的限制类似。

以下属性既适用于队列目的地,也适用于主题目的地:

以下属性只适用于队列目的地:

有关物理目的地属性的完整参考信息,请参见第 15 章,物理目的地属性参考

对于自动创建的目的地,在代理的实例配置文件中设置默认属性值。有关自动创建的属性的参考信息,请参见表 14–3

列出物理目的地

可以获得有关物理目的地的当前属性值、与物理目的地关联的生成方和使用方的数量以及消息传送度量(例如,物理目的地中消息的数量和大小)的信息。

要找到您希望获取其信息的物理目的地,请使用 list dst 子命令列出代理中的所有物理目的地。 下面是 list dst 子命令的语法:

list dst [-t destType] [-tmp]

该命令列出指定类型的物理目的地。目的地类型 (-t) 选项的值可以是 q(queue,队列)或 t(topic,主题)。

如果省略目的地类型,将列出所有类型的物理目的地。

list dst 子命令可以选择指定要列出的目的地的类型或包含临时目的地(使用 -tmp 选项)。临时目的地由客户端创建,通常用于接收发送到其他客户端的消息的回复。

例如,要获得在 myHost 端口 4545 上运行的代理中的所有物理目的地列表,请输入以下命令:

imqcmd list dst -b myHost:4545

除非指定目的地类型 t(表示只包括主题),否则,除其他所有物理目的地外,还始终会显示停用消息队列 mq.sys.dmq 的信息。

显示有关物理目的地的信息

要获得有关物理目的地当前属性的信息,请使用 query dst 子命令。下面是 query dst 子命令的语法:

query dst -t destType -n 
destName

此命令列出有关指定类型和名称的目的地的信息。例如,以下命令显示有关队列目的地XQueue 的信息:

imqcmd query dst -t q -n XQueue -u admin

此命令将产生类似如下内容的输出:


------------------------------------
Destination Name    Destination Type
------------------------------------
XQueue              Queue

On the broker specified by:

-------------------------
Host         Primary Port
-------------------------
localhost    7676

Destination Name                      XQueue
Destination Type                      Queue
Destination State                     RUNNING
Created Administratively              true

Current Number of Messages            0
Current Total Message Bytes           0
Current Number of Producers           0
Current Number of Active Consumers    0
Current Number of Backup Consumers    0

Max Number of Messages                unlimited (-1)
Max Total Message Bytes               unlimited (-1)
Max Bytes per Message                 unlimited (-1)
Max Number of Producers               100
Max Number of Active Consumers        1
Max Number of Backup Consumers        0

Limit Behavior                        REJECT_NEWEST
Consumer Flow Limit                   1000
Is Local Destination                  false
Local Delivery is Preferred           false
Use Dead Message Queue                true

输出还显示与目的地关联的生成方和使用方的数量。对于队列目的地,该数量包括活动使用方和备份使用方。

可以使用 update dst 子命令更改一个或多个属性的值(请参见更新物理目的地属性)。

更新物理目的地属性

可以使用 update dst 子命令更改物理目的地的属性,并使用 -o 选项指定要更新的属性。 下面是 update dst 子命令的语法:

update dst -t destType -n 
destName -o property=value [[-o 
property=value1]…]

此命令更新指定目的地上指定属性的值。属性名可以是表 15–1 中列出的任何属性。

可以使用 -o 选项多次更新多个属性。 例如,以下命令将 maxBytesPerMsg 属性更改为 1000,同时将 MaxNumMsgs 属性更改为 2000

imqcmd update dst -t q -n myQueue -o “maxBytesPerMsg=1000”
              -o “maxNumMsgs=2000” -u admin

有关可以更新的属性列表,请参见第 15 章,物理目的地属性参考

不能使用 update dst 子命令更新物理目的地的类型或更新 isLocalOnly 属性。


注 –

停用消息队列是专用的物理目的地,其属性与其他目的地的属性稍有不同。有关详细信息,请参见使用停用消息队列


暂停和恢复物理目的地

可暂停物理目的地以控制从生成方到目的地的消息传送,或从目的地到使用方的消息传送,或者同时控制二者。特别是,可暂停到目的地的消息流,以防止当消息的生成速度明显快于使用速度时,目的地由于所包含的消息过多而过载。 压缩物理目的地之前,必须先暂停它。

要暂停流入或流出物理目的地的消息传送,请使用 pause dst 子命令。下面是 pause dst 子命令的语法:

pause dst [-t destType -n 
destName] [-pst pauseType]

对于指定类型和名称的目的地,此子命令暂停将消息传送给使用方 (-pst CONSUMERS ),或暂停从生成方传送消息 (-pst PRODUCERS),或同时暂停二者 ( -pst ALL)。如果未指定目的地类型和名称,则暂停所有物理目的地。默认值为 ALL

示例:

imqcmd pause dst -n myQueue -t q -pst PRODUCERS -u admin
imqcmd pause dst -n myTopic -t t -pst CONSUMERS -u admin

要恢复向暂停目的地的传送,请使用 resume dst 子命令。下面是 resume dst 子命令的语法:

resume dst [-t destType -n 
destName]

此子命令恢复向指定类型和名称的暂停目的地传送消息。如果未指定目的地类型和名称,则恢复所有目的地。

示例:

imqcmd resume dst -n myQueue -t q

在代理群集中,物理目的地实例位于群集的各个代理中。 必须逐一暂停各个目的地。

清除物理目的地

可以清除物理目的地上当前排队的所有消息。清除物理目的地意味着目的地上存储的所有消息都将被删除。

当堆积的消息占用了过多的系统资源时,可能需要清除消息。当某个队列没有注册的使用方客户端,但仍然接收大量消息时,可能会发生这种情况。如果某个主题的长期订户始终处于非活动状态也可能发生这种情况。在上述两种情况下,都没有必要保留消息。

要清除物理目的地中的消息,请使用 purge dst 子命令。下面是 purge dst 子命令的语法:

purge dst -t destType -n 
destName

此子命令清除指定类型和名称的物理目的地中的消息。

示例:

imqcmd purge dst -n myQueue -t q -u admin
imqcmd purge dst -n myTopic -t t -u admin

如果关闭代理后不希望在重新启动代理时传送过时消息,请使用 -reset messages 选项清除过时消息;例如:

imqbrokerd -reset messages -u admin

这样可以避免重新启动代理后清除目的地的麻烦。

在代理群集中,物理目的地实例位于群集的各个代理中。必须分别清理每个目的地。

销毁物理目的地

要销毁物理目的地,请使用 destroy dst 子命令。下面是 destroy dst 子命令的语法:

destroy dst -t destType -n 
destName

该子命令销毁指定类型和名称的物理目的地。

示例:

imqcmd destroy dst -t q -n myQueue -u admin

销毁物理目的地将清除该目的地中的所有消息并将该目的地从代理中删除,此操作是不可逆的。

不能销毁停用消息队列。

压缩物理目的地

如果使用基于文件的数据存储库作为消息的持久性存储库,则可以监视磁盘使用情况并在必要时压缩磁盘。

可构建基于文件的消息存储库,以便将消息存储在与保存它的物理目的地对应的目录中。在每个物理目的地的目录中,大多数消息都存储在一个由大小可变的记录组成的文件中。 (为减少文件碎片,大小超过可配置阈值的消息将存储在单独的文件中。)

由于各种大小的消息先持久化,然后从记录文件中删除,因此可能会在文件中形成漏洞,从而使得文件中的空闲记录无法再次使用。

为管理未使用的空闲记录,命令实用程序包含用于监视每个物理目的地的磁盘利用率的子命令,以及在磁盘利用率降低时用于回收空闲磁盘空间的子命令。

监视物理目的地的磁盘利用率

要监视物理目的地的磁盘利用率,请使用如下所示的命令:

imqcmd metrics dst -t q -n myQueue -m dsk -u admin

此命令将产生类似如下内容的输出:


--------------------------------------
Reserved   Used      Utilization Ratio
--------------------------------------
806400     804096    99
1793024    1793024   100
2544640    2518272   98

子命令输出中的各列具有以下含义:

表 6–2 物理目的地磁盘占用度量

度量 

描述 

保留的

所有记录使用的磁盘空间(以字节为单位),其中包括保存活动消息的记录以及等待再次使用的空闲记录。 

已用的

保存活动消息的记录使用的磁盘空间(以字节为单位)。 

利用率

已用的磁盘空间除以保留的磁盘空间所得的商。 比率越高,可用于保存活动消息的磁盘空间就越多。

回收未使用的物理目的地磁盘空间

磁盘利用模式取决于使用特定物理目的地的消息发送应用程序的特征。根据流入和流出物理目的地的消息的相对数量,以及消息的相对大小,保留的磁盘空间可能会随时间而增加。

如果消息生产率大于消息使用率,则通常应该重新使用空闲记录,且应提高利用率。但是,如果消息生产率等于或小于消息使用率,则应降低利用率。

通常,应尽量使保留的磁盘空间保持一个稳定的量,并使磁盘利用率保持较高水平。一般规则是:如果系统达到稳定状态(其中保留的磁盘空间量较为稳定),且磁盘利用率较高(大于 75%),则不必回收未使用的磁盘空间。 如果系统达到稳定状态,而利用率较低(低于 50%),则可压缩磁盘以回收空闲记录占用的磁盘空间。

可以使用 compact dst 子命令压缩数据存储库。 下面是 compact dst 子命令的语法:

compact dst [-t destType -n 
destName]

此子命令为指定类型和名称的物理目的地压缩基于文件的数据存储库。如果未指定目的地类型和名称,则会压缩所有目的地。 压缩之前必须先暂停物理目的地。

如果保留的磁盘空间随时间持续增加,请通过设置目的地内存限制属性和限制行为来重新配置目的地的内存管理(请参见表 15–1)。

Procedure回收未使用的物理目的地磁盘空间

  1. 暂停目的地。


    imqcmd pause dst -t q -n myQueue -u admin
  2. 压缩磁盘。


    imqcmd compact dst -t q -n myQueue -u admin
  3. 恢复物理目的地。


    imqcmd resume dst -t q -n myQueue -u admin

    如果未指定目的地类型和名称,则会为所有物理目的地执行此操作。

使用停用消息队列

停用消息队列 mq.sys.dmq 是系统创建的物理目的地,它保存代理的停用消息及其他物理目的地。 停用消息队列是一个工具,用于监视、调整系统效率以及故障排除。有关术语“停用消息”的定义以及停用消息队列的更详细介绍,请参见 Message Queue 技术概述

代理在启动时会自动创建停用消息队列。如果代理无法处理消息或者消息的有效期到期,则代理会将消息放入该队列中。另外,其他物理目的地也可以使用停用消息队列来保存丢弃的消息。通过使用停用消息队列,可以提供有利于排除系统故障的信息。

配置停用消息队列的使用

默认情况下,物理目的地配置为使用停用消息队列。可以通过设置物理目的地属性 useDMQ 来禁止或允许物理目的地使用停用消息队列。

下面的示例创建一个名为 myDist 的队列,该队列在默认情况下使用停用消息队列:

imqcmd create dst -n myDist -t q

下面的示例禁止上述队列使用停用消息队列:

imqcmd update dst -n myDist -t q -o useDMQ=false

通过设置 imq.autocreate.destination.useDMQ 代理属性,可以允许或禁止代理中所有自动创建的物理目的地使用停用消息队列。

管理停用消息队列

可以使用 Message Queue 命令实用程序 (imqcmd) 像管理其他队列那样来管理停用消息队列,但有一些不同之处。 例如,由于停用消息队列是系统创建的,因此您不能创建、暂停或销毁它。另外,如表 6–3 中所示,停用消息队列的默认值有时与普通队列的默认值不同。

停用消息队列属性

配置停用消息队列与配置其他队列相似,但某些物理目的地属性不应用默认值或具有不同的默认值。表 6–3 列出了停用消息队列以独特方式处理的队列属性。

表 6–3 标准物理目的地属性的停用消息队列处理

属性 

停用消息队列的独特处理 

limitBehavior

停用消息队列的默认值为 REMOVE_OLDEST。(其他队列的默认值为 REJECT_NEWEST)停用消息队列不支持流控制。

localDeliveryPreferred

不适用于停用消息队列。 

maxNumMsgs

停用消息队列的默认值为 1000。对于其他队列,默认值为 -1(无限制)。

maxNumProducers

不适用于停用消息队列。 

maxTotalMsgBytes

对于停用消息队列,默认值为 10 MB。对于其他队列,默认值为 -1(无限制)。

isLocalOnly

在代理群集中,停用消息队列始终是全局物理目的地,此属性永久性地设置为 false

消息内容

代理可以将完整的消息放入停用消息队列中,也可以丢弃消息主体内容,而只保留标题和属性数据。默认情况下,停用消息队列存储完整的消息。

如果要减小停用消息队列的大小并且不打算恢复停用消息,请考虑将 imq.destination.DMQ.truncateBody 代理属性设置为 true

imqcmd update bkr -o imq.destination.DMQ.truncateBody=true

这将丢弃消息主体,而只保留标题和属性数据。

启用停用消息日志记录

默认情况下将禁用停用消息日志记录。启用停用消息日志记录使代理可以记录以下事件:

以下命令启用停用消息日志记录:

imqcmd update bkr -o imq.destination.logDeadMsgs=true

停用消息日志记录适用于使用停用消息队列的所有物理目的地。不能对单个物理目的地启用或禁用日志记录。

第 7 章 管理安全性

您可以配置用户系统信息库来验证用户、定义访问控制、配置用来加密客户端/代理通信的安全套接字层 (Secure Socket Layer, SSL) 连接服务,并设置代理启动时使用的密码文件。

本章包含以下各节:

用户验证

当用户尝试连接到代理时,代理将通过检查所提供的名称和密码来对用户进行验证。如果名称和密码与特定于代理的(每个代理均配置为需要查阅)用户系统信息库中的名称和密码相匹配,则允许该用户与代理建立连接。

您负责维护系统信息库中用户、用户组及用户密码的列表。各个代理实例可以使用不同的用户系统信息库。本节将说明如何创建、填充和管理系统信息库。

系统信息库可以是以下类型之一:

使用平面文件用户系统信息库

Message Queue 提供了一个平面文件用户系统信息库和一个命令行工具,即用户管理器实用程序 (imqusermgr),您可以使用它来填充和管理平面文件用户系统信息库。以下各节介绍平面文件用户系统信息库以及如何使用用户管理器实用程序来填充和管理该系统信息库。

创建用户系统信息库

平面文件用户系统信息库是特定于实例的。默认的用户系统信息库(名为 passwd)是为启动的每个代理实例自动创建的。此用户系统信息库所在的目录由与该系统信息库相关联的代理实例的名称标识(请参见附录 A, Message QueueTM 数据在特定平台上的位置):

   …/instances/instanceName/etc/passwd

创建的系统信息库具有两个条目。表 7–1 中的每一行显示一个条目。

表 7–1 用户系统信息库中的初始条目

用户名 

密码 

组 

状态 

admin

admin

admin

处于活动状态

guest

guest

anonymous

处于活动状态

这些初始条目使 Message Queue 代理安装后即可使用,不需要管理员的干预:

以下各节说明如何填充和管理平面文件用户系统信息库。

用户管理器实用程序

使用 Message Queue 用户管理器实用程序 (imqusermgr),您可以编辑或填充平面文件用户系统信息库。本节介绍了用户管理器实用程序。下文说明如何使用 imqusermgr 子命令完成特定任务。

有关 imqusermgr 命令的完整参考信息,请参见第 13 章,命令行参考

使用用户管理器之前,请谨记以下事项:


注 –

以下各节中的示例采用默认代理实例。


子命令

imqusermgr 命令包含子命令 adddeletelistupdate

命令选项

表 7–2 列出了 imqusermgr 命令的选项。

表 7–2 imqusermgr 选项

选项 

描述 

-a activeState

指定用户是否处于活动状态 (true/false)。true 表示处于活动状态。这是默认值。

-f

执行操作,无需用户确认。 

-h

显示用法帮助。不执行命令行上的其他选项。 

-i instanceName

指定命令要应用到的代理实例名。如果未指定,则采用默认实例名 imqbroker

-p passwd

指定用户密码。 

-g group

指定用户组。有效值包括 adminuseranonymous

-s

设置无提示模式。 

-u userName

指定用户名。 

-v

显示版本信息。不执行命令行上的其他选项。 

在代理实例的用户系统信息库中添加用户条目时,可以指定以下三个预定义组之一: adminuseranonymous。如果不指定任何组,则默认属于 user 组。应按如下方式指定组:

要更改用户所属的组,必须删除该用户的条目,然后为该用户添加另一个条目并为其指定新组。

您不能重命名或删除这些系统创建的组,也不能创建新组。但是,您可以指定访问规则,以定义该组的成员可以执行的操作。有关详细信息,请参见用户授权:访问控制属性文件

用户状态

向系统信息库中添加用户时,用户的默认状态是活动的。要使用户处于非活动状态,您必须使用 update 命令。例如,以下命令将使用户 JoeD 处于非活动状态:

imqusermgr update -u JoeD -a false

处于非活动状态的用户条目将保留在系统信息库中,但不能打开新连接。当某个用户处于非活动状态时,如果您试图添加具有相同名称的另一个用户,操作将失败。必须删除处于非活动状态的用户条目,或者更改新用户的名称,或者为新用户指定一个不同的名称。这样可以防止添加重复的用户名。

用户名和密码的格式

用户名和密码必须遵循以下原则:

填充和管理用户系统信息库

要在系统信息库中添加用户,可以使用 add 子命令。例如,以下命令向默认代理实例用户系统信息库添加用户名为 Katharine、密码为 sesame 的用户。

imqusermgr add -u Katharine -p sesame -g user

要从系统信息库中删除用户,可以使用 delete 子命令。例如,以下命令删除用户 Bob

imqusermgr delete -u Bob

要更改用户的密码或状态,可以使用 update 子命令。例如,以下命令将 Katharine 的密码更改为 aladdin

imqusermgr update -u Katharine -p aladdin

要列出一个或所有用户的相关信息,可以使用 list 命令。以下命令显示名为 isa 的用户的相关信息:

imqusermgr list -u isa

% imqusermgr list -u isa

User repository for broker instance: imqbroker
----------------------------------
User Name    Group    Active State
----------------------------------
isa          admin    true

以下命令列出所有用户的相关信息:

imqusermgr list

% imqusermgr list

User repository for broker instance: imqbroker
--------------------------------------
User Name    Group        Active State
--------------------------------------
admin        admin        true
guest        anonymous    true
isa          admin        true
testuser1    user         true
testuser2    user         true
testuser3    user         true
testuser4    user         false
testuser5    user         false

更改默认的管理员密码

为安全起见,应该将 admin 的默认密码更改为只有您自己知道的密码。以下命令将 mybroker 代理实例的默认管理员密码 admin 更改为 grandpoobah

imqusermgr update mybroker -u admin -p grandpoobah

要快速确认此更改是否已生效,可以在代理实例运行时运行任何命令行工具。例如,以下命令将提示您输入密码:

imqcmd list svc mybroker -u admin

输入新密码 (grandpoobah) 将会被接受;而输入旧密码则会失败。

更改密码后,使用任何 Message Queue 管理工具(包含管理控制台)时都应该提供新密码。

使用 LDAP 服务器管理用户系统信息库

要使用 LDAP 服务器来管理用户系统信息库,请执行以下任务:

编辑实例配置文件

要让代理使用目录服务器,请设置代理实例配置文件 config.properties 中某些属性的值。设置这些属性后,每当用户试图连接到代理实例或执行消息传送操作时,代理实例都会在 LDAP 服务器中查询有关用户和组的信息。

实例配置文件位于代理实例目录下的某个目录中。路径的格式如下:

/instances/instanceName

/props/config.properties

有关实例目录在特定操作系统中的位置的信息,请参见附录 A, Message QueueTM 数据在特定平台上的位置

Procedure编辑配置文件以使用 LDAP 服务器

  1. 通过设置以下属性,指定您使用的是 LDAP 用户系统信息库:


    imq.authentication.basic.user_repository=ldap
  2. 设置 imq.authentication.type 属性,确定密码是以 Base64 (basic) 还是 MD5 (digest) 编码的形式从客户端传递给代理。使用 LDAP 目录服务器管理用户系统信息库时,必须将验证类型设置为 basic。例如,


    imq.authentication.type=basic
  3. 还必须设置控制 LDAP 访问的代理属性。这些属性存储在代理的实例配置文件中。安全服务对这些属性进行了讨论,安全属性对这些属性进行了总结。

    Message Queue 使用 JNDI API 与 LDAP 目录服务器进行通信。有关这些属性的语法及其所引用的术语的详细信息,请查阅 JNDI 文档。Message Queue 使用 Sun JNDI LDAP 提供者并使用简单验证。

    Message Queue 支持 LDAP 验证故障转移:可以指定要尝试进行验证的 LDAP 目录服务器列表(请参见 imq.user.repos.ldap.server 属性的参考信息)。

    有关说明如何设置 LDAP 用户系统信息库相关属性的示例,请参见代理的 config.properties 文件。

  4. 必要时,还需要编辑访问控制属性文件中的用户/组和规则。有关使用访问控制属性文件的详细信息,请参见用户授权:访问控制属性文件

  5. 如果您希望代理在连接验证和组搜索时通过 SSL 与 LDAP 目录服务器进行通信,您需要在 LDAP 服务器中激活 SSL,然后在代理配置文件中设置以下属性:

    • 指定 LDAP 服务器进行 SSL 通信时所使用的端口。例如:


      imq.user_repository.ldap.server=myhost:7878
    • 将代理属性 imq.user_repository.ldap.ssl.enabled 设置为 true

      使用多个 LDAP 目录服务器时,可以使用 ldap:// 指定每个额外的目录服务器。例如:

      imq.user_repository.ldap.server = myHost:7878 ldap:// otherHost:7878

      用空格分隔每个额外的目录服务器。对于其他与 LDAP 相关的属性,列表中的所有目录服务器必须使用相同的值。

为管理员设置访问控制

要创建管理用户,请使用访问控制属性文件指定能够创建 ADMIN 连接的用户和组。必须在 LDAP 目录中预定义这些用户和组。

能够创建 ADMIN 连接的任何用户或组都可以执行管理命令。

Procedure设置管理用户

  1. 将代理属性 imq.accesscontrol.enabled 设置为 true(默认值),以允许使用访问控制文件。

    imq.accesscontrol.enabled 属性允许使用访问控制文件。

  2. 打开访问控制文件 accesscontrol.properties附录 A, Message QueueTM 数据在特定平台上的位置 中列出了该文件的位置。

    该文件包含一个如下所示的条目:

    service connection access control##################################connection.NORMAL.allow.user=*connection.ADMIN.allow.group=admin

    列出的条目是示例。请注意,admin 组存在于基于文件的用户系统信息库中,而非默认存在于 LDAP 目录中。您必须将在 LDAP 目录中定义的组的名称替换为要为其授予 Message Queue 管理员权限的组的名称。

  3. 要为用户授予 Message Queue 管理员权限,请按如下所示输入用户名:

    connection.ADMIN.allow.user= userName[[,userName2] ]

  4. 要为组授予 Message Queue 管理员权限,请按如下所示输入组名称:

    connection.ADMIN.allow.group= groupName[[,groupName2] ]

用户授权:访问控制属性文件

访问控制属性文件(ACL 文件)包含一些规则,用来指定用户和用户组可以执行的操作。您可以编辑 ACL 文件,将操作限定给某些用户和组。各个代理实例可以使用不同的 ACL 文件。

无论用户信息是放在平面文件用户系统信息库中还是放在 LDAP 用户系统信息库中,都会使用 ACL 文件。当客户端应用程序执行以下操作之一时,代理将会检查其 ACL 文件:

代理将检查 ACL 文件,以确定是授权生成请求的用户还是用户所属的组来执行该操作。

如果对 ACL 文件进行编辑,新的设置将在下一次代理检查该文件以验证授权时生效。编辑完文件后,不需要重新启动代理。

创建访问控制属性文件

ACL 文件是特定于实例的。每次启动代理实例时,都会在该实例目录中创建一个名为 accesscontrol.properties 的默认文件。该文件的路径为如下格式(请参见附录 A, Message QueueTM 数据在特定平台上的位置):

…/instances/brokerInstanceName/etc/accesscontrol.properties

ACL 文件的格式与 Java 属性文件类似。首先定义文件的版本,然后指定访问控制规则,规则分为三部分:

version 属性定义 ACL 属性文件的版本,不能更改此条目。

version=JMQFileAccessControlModel/100

下面说明访问规则的基本语法并介绍如何计算权限,然后介绍指定访问控制的 ACL 文件的三个组成部分。

访问规则语法

ACL 属性文件中,访问控制用于定义特定用户或组对受保护的资源(如物理目的地和连接服务)具有哪些访问权限。访问控制由一个规则或一组规则组成,每个规则都由一个 Java 属性表示:

这些规则的基本语法如下:

resourceType.resourceVariant

.operation.access.
principalType=principals

表 7–3 介绍了语法规则的元素。

表 7–3 访问规则的语法元素

元素 

描述 

resourceType

以下选项之一:connectionqueuetopic

resourceVariant

resourceType 指定的类型的一个实例。例如,myQueue。通配符 (*) 可用于表示所有连接服务类型或所有物理目的地。

operation

值取决于所设置的访问规则的类型。 

access

以下选项之一:allowdeny

principalType

以下选项之一:usergroup。有关详细信息,请参见

principals

可能具有规则左侧指定的访问权限的人。如果 principalTypeuser,则可能是单个用户或以逗号分隔的用户列表;如果 principalTypegroup,则可能是单个组或以逗号分隔的组列表。通配符 (*) 可用于表示所有用户或所有组。

下面是一些访问规则示例:


注 –

要指定非 ASCII 的用户、组或目的地名称,请使用 Unicode 转义符 (\\uXXXX) 表示法。如果在您编辑并保存的 ACL 文件中,这些名称采用了非 ASCII 编码,则可以通过 Java native2ascii 工具将此文件转换为 ASCII。有关更多详细信息,请参见

http://java.sun.com/j2se/1.4/docs/guide/intl/faq.html

权限的计算方式

当文件中存在多个访问规则时,将按如下方式计算权限:

用于连接服务的访问控制

ACL 属性文件中的连接访问控制部分包含代理连接服务的访问控制规则。连接访问控制规则的语法如下:

connection.resourceVariant.
access.principalType=
principals

resourceVariant 定义了两个值:NORMALADMIN。这些预定义的值是您唯一能够授予访问权限的连接服务类型。

默认的 ACL 属性文件授予所有用户访问 NORMAL 连接服务的权限,并授予 admin 组中的用户访问 ADMIN 连接服务的权限:

connection.NORMAL.allow.user=*
connection.ADMIN.allow.group=admin

如果您使用的是基于文件的用户系统信息库,则默认组 admin 由用户管理器实用程序创建。如果您使用的是 LDAP 用户系统信息库,则可以通过执行以下操作之一来使用默认 ACL 属性文件:

您可以对连接访问权限加以限定。例如,以下规则拒绝 Bob 访问 NORMAL,但允许其他人访问:

connection.NORMAL.deny.user=Bob
connection.NORMAL.allow.user=*

可以使用星号 (*) 指定所有通过验证的用户或组。

使用 ACL 属性文件来授权访问 ADMIN 连接的方式与使用基于文件的用户系统信息库和 LDAP 用户系统信息库不同,如下所示:

对物理目的地的访问控制

访问控制属性文件的目的地访问控制部分包含基于物理目的地的访问控制规则。这些规则决定谁(用户/组)可以在哪里(物理目的地)执行什么(操作)。这些规则控制的访问类型包括向队列发送消息、向主题发布消息、从队列接收消息、订阅主题以及浏览队列中的消息。

默认情况下,任何用户或组都可以对任何物理目的地进行任意类型的访问。您可以添加更多特定的目的地访问规则或编辑默认的规则。本节的余下部分介绍物理目的地访问规则的语法,您必须理解这些语法才能编写自己的规则。

目的地规则的语法如下:

resourceType.resourceVariant.operation.access.principalType=principals

表 7–4 介绍了这些元素:

表 7–4 物理目的地访问控制规则的元素

组件 

描述 

resourceType

可以是 queuetopic

resourceVariant

某个物理目的地名或所有物理目的地 (*),星号表示所有队列或所有主题。 

operation

可以是 produceconsume browse

access

可以是 allowdeny

principalType

可以是 usergroup

可以将访问权限授予一个或多个用户和/或组。

以下示例说明了不同类型的物理目的地访问控制规则:

对自动创建的物理目的地的访问控制

ACL 属性文件最后一部分所包括的访问规则指定代理将为哪些用户和组自动创建物理目的地。

当用户在尚不存在的物理目的地上创建生成方或使用方时,如果已启用代理的自动创建属性,则代理将会创建该目的地。

默认情况下,任何用户或组都有权让代理为其自动创建一个物理目的地。此权限由以下规则指定:

queue.create.allow.user=*
topic.create.allow.user=*

您可以编辑 ACL 文件以限制此类访问权限。

物理目的地自动创建访问规则的一般语法如下:

resourceType.create.access.principalType=principals

其中 resourceTypequeuetopic

例如,以下规则允许代理为除 Snoopy 之外的每个用户自动创建 topic 目的地。

topic.create.allow.user=*
topic.create.deny.user=Snoopy

请注意,物理目的地自动创建规则的效果必须与物理目的地访问规则的效果一致。例如,如果您 1) 更改目的地访问规则,禁止任何用户向目的地发送消息;但是 2) 启用了目的地的自动创建,那么如果目的地不存在,代理创建一个物理目的地,但不会向该目的地发送任何消息。

消息加密

本节将说明如何设置基于安全套接字层 (Secure Socket Layer, SSL) 标准的连接服务,此连接服务在客户端与代理之间发送加密的消息。Message Queue 支持以下基于 SSL 的连接服务:

本节后面部分将介绍如何使用 ssljms ssladmincluster 连接服务通过 TCP/IP 建立安全连接。有关使用 httpsjms 服务通过 HTTP 建立安全连接的信息,请参见附录 C,HTTP/HTTPS 支持

使用自签名证书

要使用通过 TCP/IP 建立的基于 SSL 的连接服务,需要使用密钥工具实用程序 (imqkeytool) 生成公钥/私钥对。此实用程序将公钥嵌入自签名证书,此证书将传递给请求连接到代理的任何客户端,客户端需要使用该证书建立加密连接。本节介绍如何使用这样的自签名证书来设置基于 SSL 的服务。

如果需要更严密的验证,您可以使用由证书颁发机构验证的签名证书。若要使用签名证书,则除了使用自签名证书需要的步骤外,还需要其他一些步骤:必须先执行本节中介绍的步骤,然后再执行使用签名证书中的其他步骤。

Message Queue 对带有自签名证书的 SSL 支持用于保护所传输数据的安全性,并假定客户端正在与已知且可信任的服务器进行通信。以下过程说明了设置基于 SSL 的连接服务以使用自签名证书所需的步骤。下面各节更详细地介绍了每个步骤。

Procedure使用自签名证书设置基于 SSL 的连接服务

  1. 生成自签名证书。

  2. 在代理中启用 ssljmsssladmincluster 连接服务。

  3. 启动代理。

  4. 配置并运行客户端。

    此步骤仅适用于 ssljms 连接服务,不适用于 ssladmin cluster

生成自签名证书

运行密钥工具实用程序 (imqkeytool) 为代理生成自签名证书。(在 UNIX® 系统上,您可能需要以超级用户 (root) 身份运行该实用程序,才能获取创建密钥库的权限。)可以对 ssljmsssladmincluster 连接服务使用相同的证书。

在命令提示符下输入以下内容:

imqkeytool -broker

密钥工具实用程序会提示您输入密钥库密码:

   Generating keystore for the broker ...
   Enter keystore password:

然后,实用程序将提示您输入标识此证书所属的代理的信息。您提供的信息将构成 X.500 标识名。表 7–5 显示了一些提示和为每个提示提供的值。值区分大小写,并且可以包含空格。

表 7–5 自签名证书所需的标识名信息

提示 

X.500 属性 

描述 

示例 

您的姓名是什么?

commonName (CN)

运行代理的服务器的全限定名称 

mqserver.sun.com

您所在部门的名称是什么?

organizationalUnit (OU)

部门或分部的名称 

purchasing

您的工作单位的名称是什么?

organizationName (ON)

大型工作单位的名称,如公司或政府机构 

My Company, Inc.

您所在城市或地区的名称是什么?

localityName (L)

城市或地区的名称 

San Francisco

您所在州或省的名称是什么?

stateName (ST)

州或省的全称,不要使用缩写 

California

此单位的两字母国家/地区代码是什么?

country (C)

标准两字母国家/地区代码 

US

输入信息后,密钥工具实用程序将显示这些信息以便于您确认。例如:

   Is CN=mqserver.sun.com, OU=purchasing, ON=My Company, Inc.,
   L=San Francisco, ST=California, C=US correct?

要接受当前值并继续,请输入 yes;要重新输入值,请接受默认值或输入 no。确认后,实用程序将生成密钥对而暂停其他操作。

接下来,实用程序要求您输入密码以锁定密钥对(密钥密码)。按 Return 键响应此提示,以使用同一密码作为密钥密码和密钥库密码。


注 –

请记住您指定的密码。启动代理时必须提供此密码,代理才能打开密钥库。可以将密钥库密码存储到密码文件中(请参见密码文件)。


密钥工具实用程序生成一个自签名证书,并将其放入 Message Queue 的密钥库。密钥库所在的目录因操作系统而异,附录 A, Message QueueTM 数据在特定平台上的位置 中所示。

以下是适用于基于 SSL 连接服务的 Message Queue 密钥库的可配置属性:

有时候您可能需要重新生成密钥对才能解决某些问题:例如,如果您在启动代理时忘记了密钥库密码或基于 SSL 的服务初始化失败,并收到了异常:

java.security.UnrecoverableKeyException:Cannot recover key

(出现异常的原因可能是因为您提供的密钥密码与您生成自签名证书时的密钥库密码不同。)

Procedure重新生成密钥对

  1. 删除代理的密钥库。有关密钥库的位置,请参见附录 A, Message QueueTM 数据在特定平台上的位置

  2. 再次运行 imqkeytool 生成新密钥对,如上所述。

启用基于 SSL 的连接服务

要在代理中启用基于 SSL 的连接服务,您需要将 ssljms(或 ssladmin)添加到 imq.service.activelist 属性。

Procedure在代理中启用基于 SSL 的服务

  1. 打开代理的实例配置文件。

    实例配置文件位于一个由代理实例名称 (instanceName) 标识的目录中,而该实例名称与此配置文件是相关联的(请参见附录 A, Message QueueTM 数据在特定平台上的位置):

       .../instances/instanceName/props/config.properties
    
  2. imq.service. activelist 属性添加一个条目(如果此条目尚不存在),并将需要的基于 SSL 的服务包括在列表中。

    默认情况下,此属性包括 jmsadmin 连接服务。添加基于 SSL 的服务或希望激活的服务(ssljms 和/或 ssladmin):

    imq.service.activelist=jms,admin,ssljms,ssladmin
    

    注 –

    基于 SSL 的 cluster 连接服务是使用 imq.cluster.transport 属性启用的,而不是使用 imq.service. activelist 属性启用的;请参见连接代理


  3. 保存并关闭实例配置文件。

启动代理

启动代理并提供密钥库密码。您可以通过以下两种方式之一提供密码:


注 –

启用带有 SSL 的代理或客户端时,您可能会注意到它在几秒钟内使用了大量的 CPU 资源。这是因为 Message Queue 使用 JSSE(Java Secure Socket Extension,Java 安全套接扩展)方法 java.security.SecureRandom 来生成随机数,此方法需要大量时间生成初始随机数初始化向量。生成初始化向量后,CPU 的使用率将降到正常水平。


配置并运行基于 SSL 的客户端

配置客户端以使用基于 SSL 的连接服务的过程各有不同,具体情况取决于客户端是应用程序客户端(使用 ssljms 连接服务)还是 imqcmd 之类的 Message Queue 管理客户端(使用 ssladmin 连接服务。)

应用程序客户端

对于应用程序客户端,您必须确保客户端在其 CLASSPATH 变量中指定了 .jar 文件:

如果您使用的是 Java 2 Software Development Kit (J2SDK) 1.4 之前的版本,您还必须包括 Java 安全套接扩展 (Java Secure Socket Extension, JSSE) 和 Java 命名和目录接口 (Java Naming and Directory Interface, JNDI) .jar 文件:

(如果使用的是 J2SDK 1.4 或之后的版本,则不需要包括这些文件,因为这些版本有内置的 JSSE 和 JNDI 支持。)

正确指定了 CLASSPATH 文件之后,启动客户端并连接到代理的 ssljms 连接服务的方法之一是输入如下命令:

java -DimqConnectionType=TLS clientAppName

这将通知连接使用基于 SSL 的连接服务。

管理客户端

对于管理客户端,可以通过在调用 imqcmd 命令时包含 -secure 选项来建立一个安全的连接:例如,

imqcmd list svc -b hostName:portNumber -u adminName -secure

其中 adminName 是 Message Queue 用户系统信息库中的有效条目。该命令将提示您输入密码。(如果使用的是平面文件系统信息库,请参见更改默认的管理员密码)。

列出连接服务是验证 ssladmin 服务是否正在运行的一种方法,也可以验证是否能成功建立安全的管理连接,如以下输出所示:


Listing all the services on the broker specified by:

Host                 Primary Port
localhost            7676

Service Name     Port Number       Service State
admin            33984 (dynamic)   RUNNING
httpjms          -                 UNKNOWN
httpsjms         -                 UNKNOWN
jms              33983 (dynamic)   RUNNING
ssladmin         35988 (dynamic)   RUNNING
ssljms           dynamic           UNKNOWN

Successfully listed services.

使用签名证书

签名证书可以提供比自签名证书更严密的服务器验证。您只能在客户端与代理之间实现签名证书,而不能在群集中的多个代理之间实现签名证书。除了上面介绍的配置自签名证书的步骤外,使用签名证书还需要其他一些步骤(见下文)。以下各节更详细地介绍了这些步骤。

Procedure使用签名证书

  1. 在密钥库中安装证书。

  2. 配置 Message Queue 客户端,使其在与代理建立基于 SSL 的连接时请求签名证书。

获取和安装签名证书

以下过程说明如何获取和安装签名证书。

Procedure获取签名证书

  1. 使用 J2SE keytool 命令为上一节中生成的自签名证书生成一个证书签名请求 (Certificate Signing Request, CSR)。

    有关 keytool 命令的信息,可以参考

    http://java.sun.com/j2se/1.5.0/docs/tooldocs/solaris/keytool.html

    下面是一个示例:


    keytool -certreq -keyalg RSA -alias imq -file certreq.csr
            -keystore /etc/imq/keystore -storepass myStorePassword

    这将生成一个 CSR,它将证书封装到指定的文件中(本例中是文件 certreq.csr )。

  2. 使用 CSR 生成或请求签名证书。

    您可以通过以下两种方法之一完成:

    • 由众所周知的证书颁发机构 (Certificate Authority, CA) 签署证书,如 Thawte 或 Verisign。有关如何操作的详细信息,请参见 CA 的文档。

    • 使用 SSL 签名软件包亲自对证书进行签名。

      最终的签名证书是一个 ASCII 字符序列。如果从 CA 收到签名证书,它可能是电子邮件附件或消息文本。

  3. 将签名证书保存到文件中。

    以下说明使用示例名 broker.cer 来表示代理证书。

Procedure安装签名证书

  1. 检查 J2SE 是否默认支持您的证书颁发机构。

    此命令列出系统密钥库中的根 CA:

    keytool -v -list -keystore $JAVA_HOME/lib/security/cacerts
    

    如果您的 CA 已列出,请跳过下一步。

  2. 如果 J2SE 不支持您的证书颁发机构,请将 CA 的根证书导入到 Message Queue 密钥库中。

    下面是一个示例:

    keytool -import -alias ca -file ca.cer -noprompt -trustcacerts
            -keystore /etc/imq/keystore -storepass myStorePassword
    

    其中 ca.cer 是包含从 CA 获取的根证书的文件。

    如果您使用的是 CA 测试证书,则可能需要导入测试 CA 根证书。您的 CA 应提供有关如何获取副本的说明。

  3. 将签名证书导入到密钥库中以替换原来的自签名证书。

    下面是一个示例:

    keytool -import -alias imq -file broker.cer -noprompt -trustcacerts
            -keystore /etc/imq/keystore -storepass myStorePassword
    

    其中 broker.cer 是包含从 CA 收到的签名证书的文件。

    Message Queue 密钥库现在包含一个用于 SSL 连接的签名证书。

配置 Message Queue 客户端运行时环境以请求签名证书

现在,您必须将 Message Queue 客户端运行时环境配置为请求签名证书,并确保客户端信任对该证书进行签名的证书颁发机构。

Procedure要配置客户端运行时环境以请求签名证书

  1. 将连接工厂的 imqSSLIsHostTrusted 属性设置为 false

    默认情况下,客户端用来建立代理连接的连接工厂对象的 imqSSLIsHostTrusted 属性被设置为 true,表示客户端运行时环境将接受提供给它的任何证书。您必须将此值更改为 false,这样客户端运行时环境将尝试验证所有提供给它的证书。 如果证书签署人不在客户端的信任库中,验证将会失败。

  2. 验证签名机构是否已在客户端的信任库中注册。

    要测试客户端是否会接受由您的证书颁发机构签名的证书,请尝试建立 SSL 连接,如上文配置并运行基于 SSL 的客户端中所述。如果 CA 在客户端的信任库中,连接将会成功,您可以跳过下一步。如果连接由于证书验证错误而失败,请执行下一步。

  3. 在客户端的信任库中安装签名 CA 的根证书。

    默认情况下,客户端搜索密钥库文件 cacertsjssecacerts,因此,如果您在两个文件中的任何一个中安装了证书,则无需进行进一步的配置。以下示例将文件 testrootca.cer 中的 Verisign 证书颁发机构的测试根证书安装到默认系统证书文件 cacerts 中。该示例假定 J2SE 安装在 $JAVA_HOME/usr/j2se 目录中:

    keytool -import -keystore /usr/j2se/jre/lib/security/cacerts
            -alias VerisignTestCA -file testrootca.cer -noprompt
            -trustcacerts -storepass myStorePassword
    

    还可以(并建议)将根证书安装到可选系统证书文件 jssecacerts 中:

    keytool -import -keystore /usr/j2se/jre/lib/security/jssecacerts
            -alias VerisignTestCA -file testrootca.cer -noprompt
            -trustcacerts -storepass myStorePassword
    

    第三种可能是将根证书安装到其他密钥库文件中,并配置客户端以使用该文件作为其信任库。以下示例将根证书安装到文件 /home/smith/.keystore 中:

    keytool -import -keystore /home/smith/.keystore
            -alias VerisignTestCA -file testrootca.cer -noprompt
            -trustcacerts -storepass myStorePassword
    

    默认情况下,客户端不搜索此密钥库,因此您必须明确地向客户端提供其位置,将其用作信任库。您可以在客户端运行后,通过设置 Java 系统属性 javax.net.ssl.trustStore 执行此操作:

    javax.net.ssl.trustStore=/home/smith/.keystore
    

密码文件

多种类型的命令都需要密码。在表 7–6 中,第一列列出了需要密码的命令,第二列列出了需要密码的原因。

表 7–6 使用密码的命令

命令 

用途 

密码的用途 

imqbrokerd

启动代理 

访问基于 JDBC 的持久性数据存储库、SSL 证书密钥库或 LDAP 用户系统信息库 

imqcmd

管理代理 

验证被授权使用此命令的管理用户 

imqdbmgr

管理基于 JDBC 的数据存储库 

访问数据存储库 

可以在密码文件中指定这些密码,并使用 passfile 选项指定该文件的名称。下面是 -passfile 选项的格式:

imqbrokerd -passfile myPassfile

注 –

在以前的版本中,您可以使用 -p-password -dbpassword-ldappassword 选项在命令行指定密码。不赞成使用这些选项,在今后的版本中会将它们删除。在当前的发行版中,其中某个选项在命令行中的值将取代密码文件中相关联的值。


安全性问题

以交互方式指定密码以响应提示是最安全的密码指定方法,除非他人也可以看到您的监视器。您也可以在命令行中指定密码文件。但是,以非交互方式使用命令时,必须使用密码文件。

密码文件是未加密的,因此,您必须设置其权限以防止未经授权的访问。应设置权限以限制可以查看该文件的用户,但为启动代理的用户提供读取权限。

密码文件内容

密码文件是包含一组属性和值的简单文本文件。每个值都是由某一命令使用的密码。

密码文件可包含表 7–7 中所示的密码:

表 7–7 密码文件中的密码

密码 

受影响的命令 

描述 

imq.imqcmd.password 

+-imqcmd 

imqcmd 命令行指定管理员密码。需要对每个命令验证此密码。


imq.keystore.password

imqbrokerd 

为基于 SSL 的服务指定密钥库密码。 


imq.persist.jdbc.password

imqbrokerd
imdbmgr

指定用于打开数据库连接的密码,如有必要。 


imq.user_repository.ldap.password

imqbrokerd

指定与代理的标识名(用于绑定到已配置的 LDAP 用户系统信息库)相关联的密码。 

Message Queue 产品提供了样例密码文件。有关样例文件位置的信息,请参见附录 A, Message QueueTM 数据在特定平台上的位置

通过防火墙连接

当客户端应用程序与代理被防火墙隔开时,需要使用一些特殊的方法来建立连接。一种方法是使用 httpjmshttpsjms 连接服务(可以使用“隧道”通过防火墙);有关详细信息,请参见附录 C,HTTP/HTTPS 支持。但是 HTTP 连接比其他连接服务慢,一种更快的选择是绕过 Message Queue 端口映射器,并明确地为所需的连接服务指定静态端口地址,然后在防火墙中打开该特定端口。可以使用该方法以及 jmsssljms 连接服务(在特殊情况下,使用 adminssladmin 连接服务)通过防火墙建立连接。

表 7–8 静态端口地址的代理配置属性

连接服务 

配置属性 

jms

imq.jms.tcp.port

ssljms

imq.ssljms.tls.port

admin

imq.admin.tcp.port

ssladmin

imq.ssladmin.tls.port

Procedure启用通过防火墙的代理连接

  1. 为要使用的连接服务指定静态端口地址。

    要绕过端口映射器直接为某个连接服务指定静态端口号,请设置代理配置属性 imq.serviceName. protocolType.port,其中 serviceName 是连接服务的名称,而 protocolType 是其协议类型(请参见表 7–8)。与所有代理配置属性一样,您可以在代理的实例配置文件中指定该属性,也可以在启动代理时通过命令行指定。例如,要为 jms 连接服务指定端口号 10234,可以在配置文件中包括以下命令行:

       imq.jms.tcp.port=10234
    

    也可以在启动代理时使用以下命令:

       
    imqbrokerd  -name myBroker  -Dimq.jms.tcp.port=10234
    
  2. 配置防火墙以允许连接到为连接服务指定的端口号。

    您还必须允许连接能通过防火墙连接到 Message Queue 的端口映射器端口(通常是 7676,除非将端口映射器重新指定到其他一些端口)。例如,在上面的示例中,需要在防火墙中打开端口 102347676

审计日志记录

Message Queue 仅在 Enterprise Edition 中支持审计日志记录。启用审计日志记录后,Message Queue 将为下列类型的事件生成记录:

要将审计记录记录到 Message Queue 代理日志文件中,请将 imq.audit.enabled 代理属性设置为 true 。日志中的所有审计记录都包含关键字 AUDIT

第 8 章 管理受管理对象

受管理对象封装特定于提供者的配置和命名信息,以便开发可以从一个 JMS 提供者移植到另一个 JMS 提供者的客户端应用程序。通常,Message QueueTM 管理员为客户端应用程序创建受管理对象,以便在获取用于发送和接收消息的代理连接时使用。

本章介绍了如何使用对象管理器实用程序 (imqobjmgr) 来创建和管理受管理对象。本章包含以下各节:

对象存储库

受管理对象放在易于使用的对象存储库中,客户端应用程序可以通过 Java 命名和目录接口 (Java Naming and Directory Interface, JNDI) 从该对象存储库中访问这些对象。可以使用两种类型的对象存储库:标准的轻量目录访问协议 (Lightweight Directory Access Protocol, LDAP) 目录服务器或本地文件系统中的目录。

LDAP 服务器对象存储库

对于生产消息传送系统,建议将 LDAP 服务器用作对象存储库。LDAP 服务器针对分布式系统而设计,它提供了在生产环境中非常有用的安全功能。

许多供应商都提供 LDAP 实现。要使用 Message Queue 管理工具管理 LDAP 服务器上的对象存储库,可能需要先配置服务器,使其可以存储 Java 对象并执行 JNDI 查找;有关详细信息,请参见随 LDAP 实现一起提供的文档。

要将 LDAP 服务器用作对象存储库,必须指定表 8–1 中所示的属性。这些属性分为以下几个类别:

表 8–1 LDAP 对象存储库属性

属性 

描述 

java.naming.factory.initial

JNDI 查找的初始上下文 

示例: 

com.sun.jndi.ldap.LdapCtxFactory

java.naming.provider.url

服务器 URL 和目录路径 

示例: 

ldap://myD.com:389/ou=mq1,o=App

其中受管理对象存储库在目录 /App/mq1 中。

java.naming.security.principal

用于验证呼叫者的主体标识 

此属性的格式取决于验证方案:例如, 

uid=homerSimpson,ou=People,o=mq

如果未指定此属性,行为将由 LDAP 服务提供者决定。 

java.naming.security.credentials

验证主体的凭证 

此属性的值取决于验证方案:例如,它可能是散列密码、明文密码、密钥或证书。 

如果未指定此属性,行为将由 LDAP 服务提供者决定。 

java.naming.security.authentication

验证的安全级别 

此属性的值为 none simplestrong 关键字中的一个。例如,如果指定 simple,则当缺少任何主体或凭证值时,系统都会提示您。 这样您可以使用一种更安全的方法来提供身份信息。

如果未指定此属性,行为将由 LDAP 服务提供者决定。 

文件系统对象存储库

Message Queue 也支持将本地文件系统中的目录用作受管理对象的对象存储库。虽然不建议在生产系统中使用这种方法,但该方法的优点是非常易于在开发环境中使用。但是,请注意,如果要将目录用作部署于多个计算机节点上的客户端的集中式对象存储库,则所有这些客户端都必须能够访问该目录。此外,可以访问该目录的所有用户均可使用 Message Queue 管理工具来创建和管理受管理对象。

要将文件系统目录用作对象存储库,必须指定表 8–2 中所示的属性。这些属性与上述 LDAP 对象存储库属性的一般含义相同;不同的是,java.naming.provider.url 属性指定保存该对象存储库的目录的路径。此目录必须存在,并且 Message Queue 管理工具用户以及将访问该存储库的客户端应用程序用户必须对该目录具有正确的访问权限。

表 8–2 文件系统对象存储库属性

属性 

描述 


java.naming.factory.initial

JNDI 查找的初始上下文 

示例: 

com.sun.jndi.fscontext.RefFSContextFactory


java.naming.provider.url

目录路径 

示例: 

file:///C:/myapp/mqobjs

受管理对象的属性

Message Queue 受管理对象有两种基本类型:


注 –

特殊的 SOAP 端点受管理对象用于 SOAP 消息传送;有关详细信息,请参见 Message Queue Developer's Guide for Java Clients


上述每种类型的受管理对象都具有一些特定属性,用于确定对象的属性和行为。本节介绍了如何使用对象管理器命令行实用程序 (imqobjmgr) 来设置这些属性;也可以使用 GUI 管理控制台进行设置,如使用受管理对象中所述。

连接工厂属性

客户端应用程序使用连接工厂受管理对象来创建与代理交换消息时使用的连接。连接工厂的属性定义了它所创建的所有连接的属性。创建连接后,将无法更改其属性;因此,配置连接属性的唯一方法就是设置用于创建连接的连接工厂的属性。

Message Queue 定义了两类连接工厂对象:

这两类对象共享相同的配置属性,可以通过这些属性来优化资源、性能和消息吞吐量。第 16 章,受管理对象属性参考详细列出并说明了这些属性,以下各节将对这些属性进行讨论:

连接处理

连接处理属性指定了要连接到的代理地址,以及如何检测连接故障并尝试重新连接(如果要求)。表 16–1 概要介绍了这些属性。

代理地址列表

最重要的连接处理属性是 imqAddressList ,该属性指定了要与之建立连接的一个或多个代理。该属性的值是一个字符串,它包含一个代理地址或者以逗号分隔的多个地址(如果是代理群集)。根据要使用的连接服务(请参见连接服务)和建立连接的方法,代理地址可以使用各种寻址方案:

表 16–2 概述了这些寻址方案。

每个代理地址的通用格式为:

scheme://address

其中 scheme 是上面列出的寻址方案之一,而 address 表示代理地址本身。用于指定地址的准确语法因寻址方案而异,如表 16–2 中的最后一列所示。表 16–3 提供了各种地址格式的示例。

在多代理群集环境中,地址列表可能包含多个代理地址。如果第一次连接尝试失败,Message Queue 客户端运行时环境将尝试连接到列表中的另一个地址,依此类推,直到尝试完列表中的所有地址为止。其他两个连接工厂属性控制上述操作的执行方式:

自动重新连接

通过将连接工厂的 imqReconnectEnabled 属性设置为 true,可以使客户端在连接失败时自动重新连接到代理。imqReconnectAttempts 属性控制尝试重新连接到给定代理地址的次数;imqReconnectInterval 指定了两次尝试之间等待的时间间隔(以毫秒为单位)。

在代理地址列表 (imqAddressList ) 指定了多个地址的代理群集中,不但可以在原始代理上恢复失败的连接,而且还可以在群集中的其他代理上恢复失败的连接。如果重新连接到原始代理失败,则客户端运行时环境将尝试连接列表中的其他地址。imqAddressListBehavior imqAddressListIterations 属性控制尝试连接地址的顺序和循环访问列表的次数,如前面一节所述。将以 imqReconnectInterval 的值(毫秒)作为时间间隔反复尝试连接每个地址,直到达到 imqReconnectAttempts 指定的最大尝试次数为止。

自动重新连接支持消息使用的所有客户端确认模式。重新建立连接之后,代理将重新传送以前传送过的所有未确认消息,并使用重新传送标志对其进行标记。应用程序代码可以使用此标志确定消息是否已使用但尚未得到确认。(但是,对于非长期订户,代理在关闭连接后不会保留消息。因此,在关闭连接时为这些订户生成的所有消息都将丢失,而不能在重新连接后进行传送。)在自动重新连接过程中将禁止生成消息;消息生成方无法向代理发送消息,直到重新建立连接为止。

自动重新连接提供连接故障转移,但不提供数据故障转移:客户端重新连接到其他代理实例时,因出现故障或断开连接的代理而保存的持久性消息和其他状态信息会丢失。尝试重新建立连接时,Message Queue 会维护客户端运行时环境提供的对象(如会话、消息使用方和消息生成方)。当连接失败时,系统也会维护临时目的地一段时间,因为客户端可能会重新连接并再次访问它们;在客户端重新连接并使用这些目的地之后,代理将会删除它们。如果重新连接时无法在代理上完全恢复客户端状态(例如,在使用事务会话时,客户端状态只在连接期间存在),将不会进行自动重新连接,而是调用该连接的异常处理程序。然后由应用程序代码捕获异常、重新连接并恢复状态。

定期测试 (Ping) 连接

可以将 Message Queue 客户端运行时环境配置成定期测试或 "ping" 连接,从而可以尽早检测出连接故障,以免在尝试传输消息时失败。对于只使用消息而不生成消息的客户端应用程序而言,这种测试尤为重要,因为如果不进行测试,这些应用程序将无法检测到连接失败。只是偶尔生成消息的客户端也可以利用此功能。

连接工厂属性 imqPingInterval 指定了 ping 连接的频率(以秒为单位)。默认情况下将此时间间隔设置为 30 秒;如果值为 -1,则表示禁用 ping 操作。

对失败的 ping 操作的响应因操作系统平台而异。在某些操作系统上,会立即向客户端应用程序的异常侦听器抛出异常。(如果客户端没有异常侦听器,则当它下次尝试使用连接时将会失败。)其他系统可能会继续尝试与代理建立连接,并缓冲后续的 ping 操作,直到某次尝试成功或缓冲区溢出为止。

客户端身份验证

表 16–4 中列出的连接工厂属性支持长期订户的客户端验证和客户端标识符设置。

客户端验证

必须对所有的代理连接尝试进行验证,方法是将用户名和密码与消息服务维护的用户系统信息库进行对照。连接工厂属性 imqDefaultUsername imqDefaultPassword 指定了创建连接时使用的默认用户名和密码(如果客户端未明确提供它们)。

对于不希望在应用程序开发和测试期间填充用户系统信息库的开发者,为方便起见,Message Queue 提供了用户名和密码均为 guest 的 guest 用户帐户。这也是 imqDefaultUsername imqDefaultPassword 属性的默认值,这样,如果未明确指定这些属性,客户端可以始终使用 guest 帐户获取连接。在生产环境中,只有在用户系统信息库中明确注册的用户,才应该访问代理连接。

客户端标识符

根据 Java 消息服务规范的要求,当代理必须为客户端维护持久性状态时,连接必须提供一个唯一的客户端标识符。Message Queue 使用这些客户端标识符来跟踪主题目的地的长期订户。如果长期订户变为非活动状态,则代理会保留与该主题有关的所有传入消息,并在订户再次处于活动状态时传送这些消息。代理通过客户端标识符来标识订户。

客户端应用程序可以使用连接对象的 setClientID 方法以编程方式设置其自身的客户端标识符,这使得很难协调客户端标识符,从而不能确保每个标识符都是唯一的。通常,为客户端创建连接时,最好让 Message Queue 自动指定一个唯一的标识符。具体方法是,将连接工厂的 imqConfiguredClientID 属性设置为具有以下格式的值:

${u}factoryID

字符 ${u} 必须是该属性值的前四个字符。(如果大括号之间是 u 以外的任何字符,都会在创建连接时抛出异常;在任何其他位置,这些字符都没有特殊含义,将被视为纯文本。)factoryID 的值是唯一与此连接工厂对象关联的字符串。

为特定客户端创建连接时,Message Queue 通过将字符 ${u} 替换为 u:userName 来构建客户端标识符,其中 userName 是通过连接验证的用户名。这可以确保给定连接工厂创建的每个连接都有其自身的唯一客户端标识符,即使它们在其他所有方面都完全相同。例如,如果用户名为 Calvin,为连接工厂的 imqConfiguredClientID 属性指定的字符串为 ${u}Hobbes ,则指定的客户端标识符将为 u:CalvinHobbes


注 –

如果两个客户端都尝试使用默认用户名 guest 获取连接,则此方案将不起作用,因为这两个客户端的客户端标识符具有相同的组成部分 ${u}。在这种情况下,只有请求连接的第一个客户端才能获取连接;第二个客户端的连接尝试将会失败,因为 Message Queue 不能创建两个具有相同客户端标识符的连接。


即使通过 imqConfiguredClientID 指定客户端标识符,客户端应用程序也可以使用连接方法 setClientID 来覆盖此设置。为了防止出现这种情况,可以将连接工厂的 imqDisableSetClientID 属性设置为 true。请注意,对于使用长期订户的应用程序,必须使用以下两种方法之一设置客户端标识符:使用 imqConfiguredClientID 以管理方式设置,或者使用 setClientID 以编程方式设置。

可靠性和流控制

由于客户端发送和接收的“有效负荷”消息和 Message Queue 自身使用的控制消息(如代理确认消息)通过同一个客户端/代理连接进行传递,因此有效负荷流量过多将会干扰控制消息的传送。为了帮助缓解这个问题,可以使用表 16–5 中列出的连接工厂属性来管理两种消息的相对流量。这些属性分为以下四个类别:

使用上述流控制技术中的任何一种都需要在可靠性和吞吐量之间进行权衡;有关详细论述,请参见客户端运行时环境消息流调整

队列浏览器和服务器会话

表 16–6 列出了影响客户端队列浏览和服务器会话的连接工厂属性。imqQueueBrowserMaxMessagesPerRetrieve 属性指定了浏览队列目的地的内容时一次可以检索的最大消息数;imqQueueBrowserRetrieveTimeout 指定了等待检索消息的最长时间。(注意 imqQueueBrowserMaxMessagesPerRetrieve 不影响浏览消息的总数,只影响它们向客户端运行时环境传送时的分块方法:分成数量少但较大的块还是数量多但较小的块。客户端应用程序将总是接收队列中的所有消息。更改该属性的值可能会影响性能,但不会影响检索的数据总量。)布尔属性 imqLoadMaxToServerSession 管理应用服务器会话中连接使用方的行为:如果此属性的值是 true,客户端将向服务器会话中装入多个消息(消息数量不超过最大消息数);如果此属性的值是 false,则客户端一次只装入一条消息。

标准消息属性

Java 消息服务规范定义了某些标准消息属性,JMS 提供者(如 Message Queue)可以选择是否支持这些属性。根据惯例,所有这些标准属性的名称均以字母 JMSX 开头。表 16–7 中列出的连接工厂属性控制 Message Queue 客户端运行时环境是否设置这些标准属性中的某些属性。对于生成的消息而言,这些属性包括:

对于使用的消息而言,这些属性包括:

消息头覆盖

对于某些 JMS 消息头字段,可以使用表 16–8 中列出的连接工厂属性来覆盖客户端设置的值。指定的设置将用于从该连接工厂获取的连接所生成的全部消息。可以采用这种方式覆盖的头字段包括:

上述每个字段都有两个属性:一个是布尔属性,用于控制是否可以覆盖字段,另一个用于指定字段的值。例如,用于设置优先级的属性是 imqOverrideJMSPriorityimqJMSPriority。此外还有一个属性 imqOverrideJMSHeadersToTemporaryDestinations,该属性控制覆盖值是否适用于临时目的地。


注 –

由于覆盖消息头可能会影响特定应用程序的需求,因此只有在咨询了应用程序的设计者或用户之后才应使用这些属性。


目的地属性

标识物理队列或主题目的地的目的地受管理对象只有两个属性,如表 16–9 中所示。一个重要属性是 imqDestinationName,该属性指定了此受管理对象表示的物理目的地的名称;此名称是使用 imqcmd create dst 命令(用于创建物理目的地)的 -n 选项指定的。(注意目的地受管理对象与它们表示的物理目的地之间不必是一对一的关系:单个物理目的地可以被多个受管理对象引用,也可以不被任何受管理对象引用。)此外,还有一个可选的描述性字符串 imqDestinationDescription,使用该字符串有助于标识目的地对象,将其与可能已经创建的其他对象区分开来。

使用对象管理器实用程序

使用 Message Queue 对象管理器实用程序 (imqobjmgr) 可以创建和管理受管理对象。imqobjmgr 命令提供了以下子命令,用于对受管理对象执行各种操作:

add

将受管理对象添加到对象存储库中

delete

从对象存储库中删除受管理对象

list

列出对象存储库中现有的受管理对象

query

显示与受管理对象有关的信息

update

修改受管理对象的属性

有关 imqobjmgr 命令的语法、子命令和选项的参考信息,请参见对象管理器实用程序

大部分对象管理器操作都要求将以下信息指定为 imqobjmgr 命令的选项:

添加受管理对象

imqobjmgr 命令的 add 子命令将连接工厂和主题或队列目的地的受管理对象添加到对象存储库中。存储在 LDAP 对象存储库中的受管理对象的查找名称必须以前缀 cn= 开头;文件系统对象存储库中的查找名称不必以任何特定前缀开头,但是不能包含正斜杠字符 (/)。


注 –

对象管理器仅列出并显示 Message Queue 受管理对象。如果对象存储库中应该包含一个非 Message Queue 对象,并且该对象与要添加的受管理对象具有相同的查找名称,则当您尝试执行添加操作时,将会收到一条错误消息。


添加连接工厂

要使客户端应用程序能够创建代理连接,请为要创建的连接类型添加连接工厂受管理对象:队列连接工厂或主题连接工厂。示例 8–1 显示了一条用于将队列连接工厂(受管理对象类型 qf)添加到 LDAP 对象存储库的命令。该对象具有查找名称 cn=myQCF,并通过 jms 连接服务连接到主机 myHost 上使用端口号 7272 运行的代理。


示例 8–1 添加连接工厂


imqobjmgr add
   -l "cn=myQCF"
   -j "java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory"
   -j "java.naming.provider.url=ldap://mydomain.com:389/o=imq"
   -j "java.naming.security.principal=uid=homerSimpson,ou=People,o=imq"
   -j "java.naming.security.credentials=doh"
   -j "java.naming.security.authentication=simple"
   -t qf
   -o "imqAddressList=mq://myHost:7272/jms"

添加目的地

创建表示目的地的受管理对象时,最好先创建物理目的地,然后将受管理对象添加到对象存储库中。可以使用命令实用程序 (imqcmd) 创建物理目的地,如创建物理目的地中所述。

示例 8–2 中显示的命令将受管理对象添加到表示某个主题目的地的 LDAP 对象存储库,该主题目的地的查找名称为 myTopic,物理目的地名称为 physTopic用于添加队列目的地的命令会很相似,但是受管理对象的类型(-t 选项)应该是 q(对应于 "queue destination")而不是 t(对应于 "topic destination")。


示例 8–2 将目的地添加到 LDAP 对象存储库


imqobjmgr add
   -l "cn=myTopic"
   -j "java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory"
   -j "java.naming.provider.url=ldap://mydomain.com:389/o=imq"
   -j "java.naming.security.principal=uid=homerSimpson,ou=People,o=imq"
   -j "java.naming.security.credentials=doh"
   -j "java.naming.security.authentication=simple"
   -t t
   -o "imqDestinationName=physTopic"

示例 8–3 显示的是同一个命令,但是受管理对象存储库在 Solaris 文件系统而不是 LDAP 服务器中。


示例 8–3 将目的地添加到文件系统对象存储库


imqobjmgr add
   -l "cn=myTopic"
   -j "java.naming.factory.initial=
           com.sun.jndi.fscontext.RefFSContextFactory"
   -j "java.naming.provider.url=file:///home/foo/imq_admin_objects"
   -t t
   -o "imqDestinationName=physTopic"

删除受管理对象

要从对象存储库中删除受管理对象,可以使用 imqobjmgr 命令的 delete 子命令,并指定要删除对象的查找名称、类型和位置。示例 8–4 中显示的命令用于删除在上述添加目的地中添加的对象。


示例 8–4 删除受管理对象


imqobjmgr delete
   -l "cn=myTopic"
   -j "java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory"
   -j "java.naming.provider.url=ldap://mydomain.com:389/o=imq"
   -j "java.naming.security.principal=uid=homerSimpson,ou=People,o=imq"
   -j "java.naming.security.credentials=doh"
   -j "java.naming.security.authentication=simple"
   -t t

列出受管理对象

使用对象管理器的 list 子命令,可以获取对象存储库中所有受管理对象或特定类型受管理对象的列表。示例 8–5 说明了如何列出 LDAP 服务器上的所有受管理对象。


示例 8–5 列出所有受管理对象


imqobjmgr list
   -j "java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory"
   -j "java.naming.provider.url=ldap://mydomain.com:389/o=imq"
   -j "java.naming.security.principal=uid=homerSimpson,ou=People,o=imq"
   -j "java.naming.security.credentials=doh"
   -j "java.naming.security.authentication=simple"

示例 8–6 列出了所有队列目的地(类型为 q)。


示例 8–6 列出特定类型的受管理对象


imqobjmgr list
   -j "java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory"
   -j "java.naming.provider.url=ldap://mydomain.com:389/o=imq"
   -j "java.naming.security.principal=uid=homerSimpson,ou=People,o=imq"
   -j "java.naming.security.credentials=doh"
   -j "java.naming.security.authentication=simple"
   -t q

查看受管理对象的信息

query 子命令显示与指定的受管理对象有关的信息,该对象使用查找名称及包含该对象的对象存储库的属性来标识。示例 8–7 显示了与查找名称 cn=myTopic 的对象有关的信息。


示例 8–7 查看受管理对象的信息


imqobjmgr query
   -l "cn=myTopic"
   -j "java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory"
   -j "java.naming.provider.url=ldap://mydomain.com:389/o=imq"
   -j "java.naming.security.principal=uid=homerSimpson,ou=People,o=imq"
   -j "java.naming.security.credentials=doh"
   -j "java.naming.security.authentication=simple"

修改受管理对象的属性

要修改受管理对象的属性,可以使用 imqobjmgr update 子命令。您应该提供该对象的查找名称和位置,并使用 -o 选项指定新的属性值。

修改受管理对象的属性更改在示例 8–8 中添加到对象存储库的队列连接工厂的 imqReconnectAttempts 属性值。


示例 8–8 修改受管理对象的属性


imqobjmgr update
   -l "cn=myQCF"
   -j "java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory"
   -j "java.naming.provider.url=ldap://mydomain.com:389/o=imq"
   -j "java.naming.security.principal=uid=homerSimpson,ou=People,o=imq"
   -j "java.naming.security.credentials=doh"
   -j "java.naming.security.authentication=simple"
   -t qf
   -o "imqReconnectAttempts=3"

使用命令文件

使用 imqobjmgr 命令的 -i 选项可以指定命令文件的名称,命令文件使用 Java 属性文件语法来表示全部或部分子命令子句。此功能在指定对象存储库属性时尤为有用,通常,指定对象存储库属性时需要执行大量的键入操作,并且在多次调用 imqobjmgr 时指定属性的操作可能相同。使用命令文件还可以避免超出命令行所允许的最大字符数。

示例 8–9 说明了对象管理器命令文件的一般语法。请注意,version 属性不是命令行选项:它指的是命令文件自身的版本(而不是 Message Queue 产品的版本),因此必须将其值设置为 2.0


示例 8–9 对象管理器命令文件语法


version=2.0
cmdtype=[ add | delete | list | query | update ]
obj.lookupName=lookup name
objstore.attrs.objStoreAttrName1=value1
objstore.attrs.objStoreAttrName2=value2
   . . .
objstore.attrs.objStoreAttrNameN=valueN
obj.type=[ q | t | cf | qf | tf | xcf | xqf | xtf | e ]
obj.attrs.objAttrName1=value1
obj.attrs.objAttrName2=value2
   . . .
obj.attrs.objAttrNameN=valueN

例如,请考虑前面示例 8–1 中显示的对象管理器命令,该命令将队列连接工厂添加到 LDAP 对象存储库。此命令可以封装在命令文件中,如示例 8–10 所示。如果将此命令文件命名为 MyCmdFile,则可以使用以下命令行来执行该命令:

imqobjmgr -i MyCmdFile

示例 8–10 示例命令文件


version=2.0
cmdtype=add
obj.lookupName=cn=myQCF
objstore.attrs.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
objstore.attrs.java.naming.provider.url=ldap://mydomain.com:389/o=imq
objstore.attrs.java.naming.security.principal=\\
                                       uid=homerSimpson,ou=People,o=imq
objstore.attrs.java.naming.security.credentials=doh
objstore.attrs.java.naming.security.authentication=simple
obj.type=qf
obj.attrs.imqAddressList=mq://myHost:7272/jms

还可以仅使用命令文件指定 imqobjmgr 子命令子句部分,而在命令行上明确提供其余部分。例如,示例 8–11 中显示的命令文件仅指定了 LDAP 对象存储库的属性值。


示例 8–11 部分命令文件


version=2.0
objstore.attrs.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
objstore.attrs.java.naming.provider.url=ldap://mydomain.com:389/o=imq
objstore.attrs.java.naming.security.principal=\\
                                       uid=homerSimpson,ou=People,o=imq
objstore.attrs.java.naming.security.credentials=doh
objstore.attrs.java.naming.security.authentication=simple

然后,可以使用此命令文件在 imqobjmgr 命令中指定对象存储库,同时明确提供其余选项,如示例 8–12 所示。


示例 8–12 使用部分命令文件


imqobjmgr add
   -l "cn=myQCF"
   -i MyCmdFile
   -t qf
   -o "imqAddressList=mq://myHost:7272/jms"

您可以根据使用的平台,从以下相应位置找到命令文件的其他示例:

Solaris:/usr/demo/imq/imqobjmgr Linux:/opt/sun/mq/examples/imqobjmgr Windows:IMQ_HOME/demo/imqobjmgr

第 9 章 使用代理群集

Message QueueTM Enterprise Edition 支持使用代理群集:代理群集是一组协同工作为客户端提供消息传送服务的代理。通过使用群集,消息服务可以将客户端连接分布在多个代理上,从而根据消息流量相应地调整自己的操作。有关群集及其工作原理的概述,请参见 Message Queue 技术概述

本章介绍如何管理代理群集,如何将代理连接到群集,以及如何配置代理群集。本章包含以下各节:

群集配置属性

可通过为群集中的每个成员代理指定群集配置属性来定义群集。可以为群集中的每个代理单独设置这些属性,但是,通常较为方便的一种做法是将这些属性收集到所有代理均引用的一个中央群集配置文件中。这样可防止设置出现不一致的情况,并确保群集中的所有代理都共享相同、一致的配置信息。

表 14–9 中详细介绍了群集配置属性。其中包括以下内容:

可以为每个代理单独设置 hostnameport 属性,但群集中所有代理的 brokerlistmasterbrokerurltransport 值必须相同。

以下部分介绍了如何设置代理的群集配置属性。可以对群集中的每个代理单独进行设置,也可以使用群集配置文件来集中进行设置。

分别为各个代理设置群集属性

可以在代理的实例配置文件(或在启动代理时的命令行)中设置代理的群集配置属性。例如,要创建由 host1 端口 9876 上的代理、host2 端口 5000 上的代理以及 ctrlhost 默认端口 (7676) 上的代理组成的群集,应在这三个代理的实例配置文件中包含以下属性:

imq.cluster.brokerlist=host1:9876,host2:5000,ctrlhost

请注意,如果采用此方法,则当群集配置需要更改时,您必须更新群集中每个代理的实例配置文件。

使用群集配置文件

为保持一致性和易维护性,建议将所有共享群集配置属性收集到一个群集配置文件中,而不是分别为每个代理设置这些属性。采用此方法时,每个代理的实例配置文件必须将 imq.cluster.url 属性设置为指向该群集配置文件的位置:例如,

imq.cluster.url=file:/home/cluster.properties

然后群集配置文件定义群集中所有代理的共享配置属性,例如要连接的代理的列表 (imq.cluster.brokerlist)、用于 cluster 连接服务的传输协议 (imq.cluster.transport) 以及(可选)主代理的地址 (imq.cluster.masterbroker)。以下代码定义了与前面的示例相同的群集,其中在 ctrlhost 上运行的代理充当主代理:

imq.cluster.brokerlist=host1:9876,host2:5000,ctrlhost
imq.cluster.masterbroker=ctrlhost

管理群集

本节介绍如何将一组代理连接成一个群集,如何在现有群集中添加新代理,以及如何从群集中删除代理。

连接代理

将代理连接成群集一般有两种方法:一种方法是通过命令行(使用 -cluster 选项)来实现,一种方法是通过在群集配置文件中设置 imq.cluster.brokerlist 属性来实现。无论采用哪种方法,启动的每个代理都每隔五秒钟就尝试与其他代理连接;在主代理(如果已配置)启动后,连接就会成功。如果群集中的某个代理在主代理之前启动,它将保持暂停状态,并拒绝客户端连接,直到主代理启动为止;之后,暂停的代理将自动进入正常运行状态。

要通过命令行配置代理群集,请在启动群集中的每个代理时使用 imqbrokerd 命令的 -cluster 选项指定群集中代理的完整列表。例如,以下命令启动一个新代理,并将它连接到在 host1 默认端口 (7676) 上运行的代理、在 host2 端口 5000 上运行的代理以及在默认主机 (localhost) 端口 9876 上运行的代理:

imqbrokerd -cluster host1,host2:5000,:9876

有一种更适用于生产系统的替代方法,即创建一个群集配置文件,它使用 imq.cluster.brokerlist 属性来指定要连接的代理的列表。然后群集中的每个代理必须将其自身的 imq.cluster.url 属性设置为指向该群集配置文件。

无论使用哪种方法,必须确保给群集中任何代理分配的地址都不会解析到网络回送 IP 地址 (127.0.0.1)。任何配置了这个地址的代理将不能连接到群集中的其他代理。


注 –

某些 Linux 安装程序自动将 localhost 条目设置为网络回送地址。在这些系统上,您必须修改系统 IP 地址,以便为群集中的所有代理设置正确的地址。

在设置群集的过程中,应针对加入群集的所有 Linux 系统检查 /etc/hosts 文件。如果系统使用静态 IP 地址,请编辑 /etc/hosts 文件以指定 localhost 的正确地址。如果地址已向域名服务 (Domain Name Service, DNS) 注册,请编辑 /etc/nsswitch.conf 文件以更改条目的顺序,使系统在查阅本地 hosts 文件前先执行 DNS 查找。/etc/nsswitch.conf 文件中的行应显示为如下顺序:

hosts:dns files

如果要在群集中的代理之间以安全加密的方式传送消息,请配置 cluster 连接服务以使用基于 SSL 的传输协议。请按照消息加密中的说明,为群集中的各个代理设置基于 SSL 的连接服务。然后,将每个代理的 imq.cluster.transport 属性设置为 ssl。可以在群集配置文件中进行此设置,也可以为每个代理单独进行此设置。

在群集中添加代理

在群集中添加新代理的步骤取决于该群集是否使用群集配置文件。

Procedure向使用群集配置文件的群集添加新代理

  1. 将新代理添加到群集配置文件中的 imq.cluster.brokerlist 属性。

  2. 对群集中的任一代理执行以下命令:


    imqcmd reload cls

    该命令强制每个代理重新加载群集配置,从而确保群集中代理的所有持久性信息都是最新的。注意,不必对群集中的每个代理都执行此命令;对任一代理执行此命令都会使所有代理重新加载群集配置。

  3. (可选)在代理的 config.properties 文件中将 imq.cluster.url 属性的值设置为指向群集配置文件。

  4. 启动新代理。

    如果未执行在群集中添加代理,请使用 imqbrokerd 命令行中的 -D 选项设置 imq.cluster.url 的值。

向未使用群集配置文件的群集添加新代理

通过编辑 config.properties 文件或者使用 imqbrokerd 命令行中的 -D 选项设置以下属性的值:

从群集中删除代理

从群集中删除代理的方法取决于群集最初是通过命令行创建的,还是通过中央群集配置文件来创建的。

使用命令行删除代理

如果群集是通过在命令行中使用 imqbrokerd 命令由代理连接而成的,则必须停止每个代理,然后通过在命令行中指定一组新的群集成员来重新启动它们。过程如下所述:

Procedure使用命令行从群集中删除代理

  1. 使用 imqcmd 命令停止群集中的每个代理。

  2. 重新启动仍然保留在群集中的代理(使用 imqbrokerd 命令的 -cluster 选项,并仅仅指定那些要保留的代理)。

    例如,假设最初创建的群集包括代理 A、B、C,而且这三个代理是通过以下命令启动的:


    imqbrokerd -cluster A,B, C
    

    要从群集中删除代理 A,请使用以下命令重新启动代理 BC


    imqbrokerd -cluster B,C
    

使用群集配置文件删除代理

如果群集最初是通过在中央群集配置文件中使用 imq.cluster.brokerlist 属性指定其成员代理来创建的,则不必停止这些代理即可删除其中的某个代理。只需编辑配置文件来排除要删除的代理,强制群集中的其他代理成员重新加载群集配置,并重新配置被排除的代理,使它不再指向原来的群集配置文件。过程如下:

Procedure使用群集配置文件从群集中删除代理

  1. 编辑群集配置文件,从为 imq.cluster.brokerlist 属性指定的列表中删除要排除的代理。

  2. 对保留在群集中的每个代理执行以下命令:


    imqcmd reload cls

    该命令强制代理重新加载群集配置。

  3. 停止要从群集中删除的代理。

  4. 编辑该代理的 config.properties 文件,删除 imq.cluster.url 属性或为该属性指定其他值。

主代理

可以选择为群集指定一个主代理。主代理维护配置更改记录以跟踪群集的持久性状态所发生的任何变化。主代理是使用 imq.cluster.masterbroker 配置属性来标识的。该属性在群集配置文件中或在单个代理的实例配置文件中。

配置更改记录包含与群集关联的持久性实体(例如长期订阅和管理员创建的物理目的地)的相关更改信息。 群集中的所有代理在启动时都会咨询主代理,以更新与这些持久性实体有关的信息。如果主代理出现故障,就无法实现上述同步;有关详细信息,请参见主代理不可用时的情况

管理配置更改记录

因为配置更改记录中包含的信息很重要,所以要定期备份配置更改记录,以便在发生故障的情况下能够恢复此记录。这一点非常重要。 虽然从备份恢复的记录不包含群集持久性状态自备份以来发生的任何更改,但经常进行备份有助于将丢失的信息降到最少。备份和恢复操作还有利于压缩和优化配置更改记录中保留的更改历史,因为该记录会随时间的推移迅速膨胀。

备份配置更改记录

使用 imqbrokerd 命令的 -backup 选项,并指定备份文件的名称。例如:

imqbrokerd -backup mybackuplog

Procedure恢复配置更改记录

  1. 关闭群集中的所有代理。

  2. 使用以下命令从备份文件中恢复主代理的配置更改记录:


    imqbrokerd -restore mybackuplog
  3. 如果为主代理分配了新的名称或端口号,请在群集配置文件中相应地更新 imq.cluster.brokerlistimq.cluster.masterbroker 属性。

  4. 重新启动群集中的所有代理。

主代理不可用时的情况

因为群集中的所有代理都需要利用主代理来执行持久性操作,因此,当主代理不可用时,群集中任一代理的以下 imqcmd 子命令都将返回一条错误消息:

自动创建的物理目的地和临时目的地均不受影响。

在没有主代理时,任何尝试创建长期订户或取消长期订阅的客户端应用程序都会收到一条错误消息。 但是,客户端可以成功地指定现有长期订阅,并与其进行交互。

第 10 章 监视代理

本章介绍可用来监视代理的工具,以及如何获得度量数据。本章包含以下各节:

第 18 章,度量参考提供了有关特定度量的参考信息。

监视工具简介

Message QueueTM 信息有三种监视接口:日志文件、交互式命令以及可获取度量的客户端 API。每一种接口都有其各自的优缺点,如下所述:

表 10–1 比较了各种不同的工具。

表 10–1 度量监视工具的优势和局限性

度量监视工具 

优势 

局限性 

imqcmd metrics

远程监视 

便于抽样检查 

在命令选项中设置报告的时间间隔;可以随时更改此时间间隔 

易于选择感兴趣的特定数据 

数据以简单的表格形式提供 

无法通过单条命令获得所有数据 

难以通过编程方式分析数据 

不创建历史记录 

难以看到历史趋势 

日志文件 

定期采样 

创建历史记录 

需要配置代理属性;必须关闭再重新启动代理才能生效 

仅限本地监视 

数据格式非常难以读取或解析;没有解析工具 

报告时间间隔不能随时更改;所有度量数据均是如此 

在数据的选择方面不提供灵活性 

仅限代理度量;目的地和连接服务度量不包括在内 

如果时间间隔设置得过短,性能可能会受影响 

客户端 API 

远程监视 

易于选择感兴趣的特定数据 

数据可以通过编程方式分析,并能够以任何格式呈现 

需要配置代理属性;必须关闭再重新启动代理才能生效 

需要编写您自己的度量监视客户端 

报告时间间隔不能随时更改;所有度量数据均是如此 

除了表中给出的不同外,每种工具收集到的具体信息(代理生成的度量信息的一部分)也稍有不同。有关每种监视工具收集的度量数据的信息,请参见第 18 章,度量参考

配置和使用代理日志记录

Message Queue 记录程序获取代理代码、调试器和度量生成器等生成的信息,并将这些信息写入多个输出通道:标准输出(控制台)、日志文件以及 Solaris™ 操作系统上的 syslog 守护进程。

您可以指定记录程序收集的信息类型以及写入每个输出通道的信息类型。特别是,您可以指定将度量信息写出到日志文件。

本节介绍了代理的默认日志记录配置,并说明了如何将日志信息重定向到替代的输出通道,如何更改日志文件转移条件,以及如何将度量数据发送到日志文件。

默认日志记录配置

代理自动配置为将日志输出保存到一组循环的日志文件中。这些日志文件位于由关联代理的实例名称标识的目录中(请参见附录 A, Message QueueTM 数据在特定平台上的位置):

…/instances/instanceName/log

注 –

对于其生命周期由应用服务器控制的代理,日志文件位于域目录(该域中启动了此代理)的子目录中:

…/appServer_domainName_dir/imq/instances/imqbroker/log

日志文件是纯文本文件。它们按如下方式命名(从最早生成到最近生成):

log.txt
log_1.txt
log_2.txt
…log_9.txt

默认情况下,日志文件每星期转移一次;系统维护九个备份文件。

代理支持三种日志级别:ERRORWARNINGINFO表 10–2 介绍了每种级别。

表 10–2 日志记录级别

级别 

描述 

ERROR

指出可能导致系统故障的问题的消息。 

WARNING

需要注意但不会导致系统故障的警报。 

INFO

度量及其他信息性消息的报告。 

设置日志记录级别后,将收集所有高于和等于该级别的消息。默认的日志级别是 INFO,因此,默认情况下会记录所有 ERRORWARNINGINFO 消息。

日志消息格式

记录的消息由时间戳、消息代码和消息本身构成。信息量取决于所设置的日志级别。下面是一个 INFO 消息的示例。


[13/Sep/2000:16:13:36 PDT] [B1004]: Starting the broker service using tcp 
[25374,100] with min threads 50 and max threads of 500

要更改时间戳时区,请参见有关 imq.log.timezone 属性的信息,表 14–8 中介绍了该属性。

更改记录程序配置

表 14–8 中介绍了与日志相关的属性。

Procedure更改代理的记录程序配置

  1. 设置日志级别。

  2. 为一个或多个日志记录类别设置输出通道(文件和/或控制台)。

  3. 如果要将输出记录到文件中,请为该文件配置转移条件。

    可以通过设置记录程序属性来完成上述步骤。可以使用以下两种方法之一来设置记录程序属性:

    • 启动代理之前,在该代理的 config.properties 文件中更改或添加记录程序属性。

    • 在启动代理的 imqbrokerd 命令中指定记录程序命令行选项。也可以使用代理选项 -D 来更改记录程序属性(或任何代理属性)。

    通过命令行传递的选项将覆盖代理实例配置文件中指定的属性。以下 imqbrokerd 选项影响日志记录:

    -metrics interval

    代理度量的日志记录时间间隔(以秒为单位)

    -loglevel level

    日志记录级别(ERRORWARNINGINFONONE

    -silent

    无提示模式(不向控制台记录消息)

    -tty

    将所有消息记录到控制台

    下面几节介绍了如何更改默认配置以执行下列操作:

    • 更改输出通道(日志消息的目的地)

    • 更改转移条件

更改输出通道

默认情况下,错误和警告消息除了记录到日志文件中以外,还会显示在终端上。(在 Solaris 中,错误消息还会写入到系统的 syslog 守护进程中。)

可以用以下方式更改日志消息的输出通道:


注 –

在更改记录程序输出通道前,必须确保日志记录级别已设置为支持映射到输出通道的信息。例如,如果将日志级别设置为 ERROR,然后将 imq.log.console.output 属性设置为 WARNING,那么将不会记录任何消息,因为没有启用 WARNING 消息的日志记录。


更改日志文件转移条件

转移日志文件有两个条件:时间和大小。默认情况下使用时间条件,每七天转移一次文件。

如果同时设置与时间和大小相关的转移属性,则转移将由最先达到的限制触发。前面已指出,代理最多维护九个转移文件。

可以在代理运行时设置或更改日志文件转移属性。要设置这些属性,请使用 imqcmd update bkr 命令。

将度量数据发送到日志文件

本节讲述使用代理日志文件报告度量信息的过程。有关配置记录程序的一般信息,请参见配置和使用代理日志记录

Procedure使用日志文件报告度量信息

  1. 配置代理的度量生成功能:

    1. 确认 imq.metrics.enabled=true

      默认情况下,用于日志记录的度量生成功能处于启用状态。

    2. 将度量生成时间间隔设置为合适的秒数。

      imq.metrics.interval=interval

      该值可以在 config.properties 文件中设置,也可以在启动代理时使用 -metrics interval 命令行选项进行设置。

  2. 确认记录程序是否收集度量信息:


    imq.log.level=INFO

    这是默认值。该值可以在 config.properties 文件中设置,也可以在启动代理时使用 -loglevel level 命令行选项进行设置。

  3. 确认记录程序是否已设置为将度量信息写入日志文件:


    imq.log.file.output=INFO

    这是默认值。它可以在 config.properties 文件中设置。

  4. 启动代理。

    下面显示了输出到日志文件的样例代理度量:


    [21/Jul/2004:11:21:18 PDT]
    Connections: 0    JVM Heap: 8323072 bytes (7226576 free) Threads: 0 (14-1010)
          In: 0 msgs (0bytes) 0 pkts (0 bytes)
         Out: 0 msgs (0bytes) 0 pkts (0 bytes)
     Rate In: 0 msgs/sec (0 bytes/sec) 0 pkts/sec (0 bytes/sec)
    Rate Out: 0 msgs/sec (0 bytes/sec) 0 pkts/sec (0 bytes/sec)

    有关度量数据的参考信息,请参见第 18 章,度量参考

记录停用消息

可以通过对代理启用停用消息日志记录来监视物理目的地。无论是否使用停用消息队列,都可以记录停用消息。

如果启用了停用消息日志记录,代理会记录以下类型的事件:

如果使用了停用消息队列,日志记录还会包括以下类型的事件:

下面是一个停用消息的日志格式示例:


[29/Mar/2006:15:35:39 PST] [B1147]: Message 8-129.145.180.87(e7:6b:dd:5d:98:aa)-
35251-1143675279400 from destination Q:q0 has been placed on the DMQ because 
[B0053]: Message on destination Q:q0 Expired: expiration time 1143675279402, 
arrival time 1143675279401, JMSTimestamp 1143675279400

默认情况下将禁用停用消息日志记录。要启用它,请设置代理属性 imq.destination.logDeadMsgs

以交互方式显示度量

Message Queue 代理可以报告以下类型的度量:

imqcmd 命令可以获取整个代理、单个连接服务以及单个物理目的地的度量信息。要获取度量数据,通常应该使用 imqcmdmetrics 子命令。度量数据将按照您指定的时间间隔或次数写到控制台屏幕上。

也可以使用 query 子命令查看也包含配置信息的类似数据。有关详细信息,请参见 imqcmd query

imqcmd metrics

imqcmd metrics 的语法和选项分别如表 10–3表 10–4 所示。

表 10–3 imqcmd metrics 子命令语法

子命令语法 

提供的度量数据 

metrics bkr
   [-b hostName:portNumber]
   [-m metricType]
   [-int interval]
   [-msp numSamples]

显示默认代理的代理度量或显示指定主机和端口上的代理的代理度量。 

metrics svc -n serviceName
   [-b hostName:portNumber]
   [-m metricType]
   [-int interval]
   [-msp numSamples]

显示默认代理或指定主机和端口上的代理中指定服务的度量。 

metrics dst -t destType
   -n destName
   [-b hostName:portNumber]
   [-m metricType]
   [-int interval]
   [-msp numSamples]

显示指定类型和名称的物理目的地的度量信息。

表 10–4 imqcmd metrics 子命令选项

子命令选项 

描述 

-b hostName: portNumber

指定报告的度量数据所对应的代理的主机名和端口。默认为 localhost:7676

-int interval

指定显示度量的时间间隔(以秒为单位)。默认为 5 秒。 

-m metricType

指定要显示的度量类型。 

ttl 显示流入和流出代理、服务或目的地的消息和包的度量(默认度量类型)。

rts 显示消息和包流入和流出代理、连接服务或目的地的速率的度量(以一秒为衡量单位)。

cxn 显示连接、虚拟内存堆和线程(仅适用于代理和连接服务)。

con 显示与使用方有关的度量(仅适用于目的地)。

dsk 显示磁盘使用情况度量(仅适用于目的地)。

-msp numSamples

指定输出中显示的样例数。默认为无限制(无穷多)。 

-n destName

指定报告的度量数据所对应的物理目的地(如果有)的名称。没有默认值。 

-n serviceName

指定报告的度量数据所对应的连接服务(如果有)。没有默认值。 

-t destType

指定报告的度量数据所对应的物理目的地(如果有)的类型(队列或主题)。没有默认值。 

使用 metrics 子命令显示度量数据

本节介绍使用 metrics 子命令报告度量信息的过程。

Procedure使用 metrics 子命令

  1. 启动需要度量信息的代理。

    请参见启动代理

  2. 使用正确的 imqcmd metrics 子命令和选项,如表 10–3表 10–4 中所示。

度量输出:imqcmd metrics

本节包含 imqcmd metrics 子命令的输出示例。这些示例显示了代理范围、连接服务和物理目的地度量。

代理范围内的度量

要获取在 10 秒的时间间隔内流入和流出代理的消息和包的速率,请使用 metrics bkr 子命令:

imqcmd metrics bkr -m rts -int 10 -u admin

此命令产生类似如下内容的输出(请参见表 18–2 中的数据说明):


--------------------------------------------------------
 Msgs/sec   Msg Bytes/sec   Pkts/sec    Pkt Bytes/sec   
 In   Out     In      Out     In   Out     In      Out  
--------------------------------------------------------
 0     0      27      56      0     0      38      66   
 10    0     7365     56      10    10    7457    1132  
 0     0      27      56      0     0      38      73   
 0     10     27     7402     10    20    1400    8459  
 0     0      27      56      0     0      38      73   

连接服务度量

要获取 jms 连接服务所处理的消息和包的累计总数,请使用 metrics svc 子命令:

imqcmd metrics svc -n jms -m ttl -u admin

此命令产生类似如下内容的输出(请参见表 18–3 中的数据说明):


-------------------------------------------------
  Msgs      Msg Bytes      Pkts      Pkt Bytes     
In   Out    In     Out   In   Out    In     Out  
-------------------------------------------------
164  100  120704  73600  282  383  135967  102127
657  100  483552  73600  775  876  498815  149948

物理目的地度量

要获取有关物理目的地的度量信息,请使用 metrics dst 子命令:

imqcmd metrics dst -t q -n XQueue -m ttl -u admin

此命令产生类似如下内容的输出(请参见表 18–4 中的数据说明):


-----------------------------------------------------------------------------
  Msgs      Msg Bytes         Msg Count         Total Msg Bytes (k)     Largest
In   Out    In     Out    Current  Peak  Avg  Current  Peak     Avg    Msg (k)
-----------------------------------------------------------------------------
200  200  147200  147200     0     200    0      0      143      71        0  
300  200  220800  147200    100    200   10     71      143      64        0  
300  300  220800  220800     0     200    0      0      143      59        0  

要获取有关物理目的地的使用方的信息,请使用下面的 metrics dst 子命令:

imqcmd metrics dst -t q -n SimpleQueue -m con -u admin

此命令产生类似如下内容的输出(请参见表 18–4 中的数据说明):


------------------------------------------------------------------
  Active Consumers         Backup Consumers         Msg Count
Current  Peak  Avg      Current  Peak    Avg    Current  Peak  Avg
------------------------------------------------------------------
   1       1      0        0       0      0       944    1000  525

imqcmd query

表 10–5 中显示了 imqcmd query 的语法和选项以及该命令所提供的度量数据的说明。

表 10–5 imqcmd query 子命令语法

子命令语法 

提供的度量数据 


query bkr
   [-b hostName: portNumber]

有关当前存储在代理内存和持久性存储库中的消息个数和消息字节数的信息(请参见显示代理信息)。

或 

 

query svc -n serviceName
  [-b  hostName:portNumber]

有关指定的连接服务的当前已分配线程数和连接数的信息(请参见显示连接服务信息)。

或 

 

query dst -t destType
  -n destName
  [-b hostName:portNumber]

有关指定目的地当前的生成方数目、活动和备份使用方的数目以及存储在内存和持久性存储库中的消息数和消息字节数的信息(请参见显示有关物理目的地的信息)。


注 –

由于 imqcmd query 提供的度量数据有限,第 18 章,度量参考的表中未提到此工具。


编写应用程序来监视代理

Message Queue 提供度量监视功能,通过该功能,代理可以将度量数据写入 JMS 消息,然后根据消息中包含的度量信息类型将它们发送到众多度量主题目的地中的一个。

您可以通过编写具有下列功能的客户端应用程序来访问这些度量信息:订阅度量主题目的地、使用这些目的地中的消息以及处理消息中包含的度量信息。

共有五个度量主题目的地,它们的名称以及传送到各个目的地的度量消息的类型显示在表 10–6 中。

表 10–6 度量主题目的地

主题名称 

度量消息的类型

mq.metrics.broker 

代理度量

mq.metrics.jvm 

Java 虚拟机度量

mq.metrics.destination_list 

目的地及其类型的列表

mq.metrics.destination.queue. monitoredDestinationName

具有指定名称的队列的目的地度量 

mq.metrics.destination.topic. monitoredDestinationName

具有指定名称的主题的目的地度量 

设置基于消息的监视

本节讲述使用基于消息的监视功能来收集度量信息的过程。此过程包括客户端开发和管理任务这两方面。

Procedure设置基于消息的监视

  1. 编写度量监视客户端。

    有关以编程方式编写订阅度量主题目的地、使用度量消息并从这些消息中提取度量数据的客户端的说明,请参见 Message Queue Developer's Guide for Java Clients

  2. 通过在 config.properties 文件中设置代理属性值来配置代理的度量消息生成方:

    1. 启用度量消息生成。

      设置 imq.metrics.topic.enabled=true

      默认值为 true

    2. 设置生成度量消息的时间间隔(以秒为单位)。

      设置 imq.metrics.topic.interval=interval

      默认值为 60 秒。

    3. 指定是否需要让度量消息成为持久性消息(即,当代理发生故障时它们是否能保留下来)。

      设置 imq.metrics.topic.persist

      默认为 false

    4. 指定在删除度量消息之前它们能在各自的目的地中保留的时间。

      设置 imq.metrics.topic.timetolive

      默认值为 300 秒。

  3. 设置需要对度量主题目的地设置的任何访问控制。

    请参见下面安全性和访问注意事项中的讨论。

  4. 启动度量监视客户端。

    当使用方订阅度量主题时,系统会自动创建度量主题目的地。创建度量主题后,代理的度量消息生成方就会开始向度量主题发送度量消息。

安全性和访问注意事项

出于以下两个原因,需要限制对度量主题目的地的访问:

出于这些方面的考虑,建议限制对度量主题目的地的访问。

用于监视目的的客户端的验证和授权控制与其他任何客户端都相同。只有用户信息保留在 Message Queue 用户系统信息库中的用户才能连接到代理。

您可以通过访问控制属性文件来限制对特定度量主题目的地的访问,从而提供更多保护,如用户授权:访问控制属性文件中所述。

例如,accesscontrol.properties 文件中的下列条目将拒绝除 user1 和 user2 之外的其他任何用户访问 mq.metrics.broker 度量主题。


topic.mq.metrics.broker.consume.deny.user=*
topic.mq.metrics.broker.consume.allow.user=user1,user2

下列条目仅允许用户 user3 监视主题 t1。


topic.mq.metrics.destination.topic.t1.consume.deny.user=*
topic.mq.metrics.destination.topic.t1.consume.allow.user=user3

根据度量数据的敏感度不同,您也可以使用加密连接将度量监视客户端连接至代理。有关使用加密连接的信息,请参见消息加密

度量输出:度量消息

使用基于消息的监视 API 获得的度量数据输出是您编写的度量监视客户端的一个功能。您只会受到代理中度量生成器提供的数据的限制。有关这些数据的完整列表,请参见第 18 章,度量参考

第 11 章 分析和调整消息服务

本章包括大量有关如何分析和调整 Message QueueTM 服务以优化消息传送应用程序性能的主题。包括以下主题:

关于性能

本节提供有关性能调整的一些背景信息。

性能调整过程

消息传送应用程序的性能取决于该应用程序与 Message Queue 服务之间的交互。因此,要获得最佳性能,需要应用程序开发者和管理员的共同努力。

优化性能的过程从应用程序设计开始,一直持续到部署应用程序之后对消息服务的调整阶段。性能调整过程包括下列阶段:

上述过程常常需要反复进行。在应用程序的部署过程中,Message Queue 管理员应该评估消息服务是否适用于应用程序的总体性能要求。如果基准测试程序测试符合这些要求,管理员就可以如本章所述调整系统。但是,如果基准检验测试不符合性能要求,则可能需要重新设计应用程序或者修改部署体系结构。

性能方面

通常,性能是对消息服务将消息从生成方传送到使用方时的速度和效率的一种衡量。但是,根据您的需要,可能会有几个不同的性能方面对您特别重要。

连接负载

系统所能支持的消息生成方、消息使用方或并发连接的数量。

消息吞吐量

每秒钟能通过消息传送系统抽取的消息数或消息字节数。

等待时间

特定消息从消息生成方传送到消息使用方所需的时间。

稳定性

消息服务的总体可用性,或者当负载较重或发生故障时性能的下降程度。

效率

消息的传送效率,这是一种与使用的计算资源相关的消息吞吐量的衡量。

这些不同的性能方面通常是相辅相成的。如果消息吞吐量很高,则意味着消息在代理上作为后备队列累积的可能性就会变小,因此等待时间也应该较低(单条消息可以很快地传送)。但是,等待时间可能取决于许多因素:通信链接的速度、代理的处理速度和客户端的处理速度,以及其他许多方面。

在任何情况下,性能都有几个不同方面。哪些方面对您最重要?这通常取决于特定应用程序的要求。

基准测试程序

基准测试是为消息传送应用程序创建测试套件,并针对此测试套件衡量消息吞吐量或其他性能方面的一种过程。

例如,您可以创建这样一个测试套件:一定数量的生成方客户端使用一定数量的连接、会话和消息生成方,将标准大小的持久性或非持久性消息按照某个特定速率发送至队列或主题(这完全取决于消息传送应用程序的设计)。同样,测试套件中还包括一定数量的使用方客户端,它们使用一定数量的连接、会话和特定类型的消息使用方(通过特定的确认模式来使用测试套件的物理目的地中的消息)。

使用标准的测试套件可以衡量消息的生成与使用之间所花的时间或者消息的平均吞吐速率,您还可以监视系统以观察连接线程使用情况、消息存储数据、消息流数据以及其他相关度量。这样就可以提高消息的生成速率、消息生成方的数量或者其他变量,直到性能受到负面影响为止。可能达到的最大吞吐量就是消息服务配置的基准。

使用此基准可以修改测试套件的某些特征。控制所有可能影响性能的因素时请小心(请参见影响性能的应用程序设计因素),您可以记录这些因素的更改如何影响基准。例如,您可以将连接数或消息大小增加五倍或十倍,并记录对性能产生的影响。

相反,您也可以将基于应用程序的因素保持不变,而以某种控制方式更改代理配置(例如,更改连接属性、线程池属性、JVM 内存限制、限制行为、基于文件与基于 JDBC 的持久性等),并记录这些更改如何影响性能。

当您需要通过调整消息服务来增加所部署的应用程序的性能时,这种应用程序基准检验可以提供非常有价值的信息。基准测试程序可用于更准确地预测所做的更改或一系列更改产生的影响。

通常,基准测试程序应该在受控制的测试环境下运行,并且运行足够长的时间,以使消息服务能够稳定。(性能在启动时会受到实时编译的负面影响,因为要将 Java 代码转换为机器代码。)

基线使用模式

部署并运行消息传送应用程序后,建立基线使用模式是很重要的。您需要知道何时发生峰值需求,并且需要能够量化该需求。例如,需求通常会随最终用户的数量、活动级别、一天当中的时间,或者以上所有这些因素而发生波动。

要建立基线使用模式,您需要在一段较长的时间内监视消息服务,并查看如下数据:

还可以使用度量数据中提供的平均值和峰值。

将这些基线度量数据与设计时的期望值进行比较是非常重要的。通过执行此操作,可以检查客户端代码是否运行正常:例如,检查连接是否未保持打开或者已使用的消息是否仍然保留在未确认状态。这些编码错误会消耗代理资源,并可能极大地影响性能。

基线使用模式有助于确定如何调整系统以优化性能。例如:

通常,您对使用模式了解得越多,就能越好地将系统调整为这些模式,并计划将来的需要。

影响性能的因素

消息等待时间和消息吞吐量是两个主要的性能指示器,它们通常取决于典型消息在完成消息传送过程中的各个步骤时所需的时间。下列步骤显示了如何以持久、可靠的方式传送消息。这些步骤将在插图之后介绍。

图 11–1 通过 Message Queue 服务传送消息

该图显示在消息传送过程中,以持久、可靠的方式传送消息的步骤。步骤在该图后面的文本中介绍。

Procedure消息传送步骤

  1. 消息从生成方客户端传送到代理。

  2. 代理读取消息。

  3. 消息被放置到持久性存储库当中(出于可靠性的考虑)。

  4. 代理确认收到消息(出于可靠性的考虑)。

  5. 代理确定消息的路由。

  6. 代理写出消息。

  7. 消息从代理传送到使用方客户端。

  8. 使用方客户端确认收到消息(出于可靠性的考虑)。

  9. 代理处理客户端确认(出于可靠性的考虑)。

  10. 代理确定已经处理客户端确认。

    因为这些步骤是连续的,所以任何步骤都可能成为消息从生成方客户端到使用方客户端的传送过程的瓶颈。这些步骤中的大多数都取决于消息传送系统的物理特征:网络带宽、计算机处理速度和消息服务体系结构等等。但是,有一些步骤还取决于消息传送应用程序的特征和该应用程序要求的可靠性级别。

    以下各节讨论应用程序设计因素和消息传送系统因素这二者对性能的影响。尽管应用程序设计和消息传送系统因素在消息传送过程中紧密交互,但它们彼此是独立的。

影响性能的应用程序设计因素

应用程序的设计决策对消息传送的总体性能有很大影响。

对性能影响最大的主要是那些影响消息传送的可靠性因素。其中包括下列因素:

其他影响性能的应用程序设计因素有:

接下来的几节讲述其中的每个因素对消息传送性能所产生的影响。通常,应当在性能与可靠性之间进行权衡。提高可靠性的因素可能会导致性能降低。

表 11–1 显示各个应用程序设计因素大体上如何影响消息传送性能。该表显示了两个方案(一个高可靠性、低性能方案和一个高性能、低可靠性方案)和分别对应于这两个方案的应用程序设计因素选项。在这两种极端情况之间,有很多可以同时影响可靠性和性能的选项和折衷。

表 11–1 高可靠性和高性能方案比较

应用程序设计因素 

高可靠性、低性能方案 

高性能、低可靠性方案 

传送模式 

持久性消息 

非持久性消息 

使用事务 

事务会话 

非事务 

确认模式 

AUTO_ACKNOWLEDGECLIENT_ACKNOWLEDGE

DUPS_OK_ACKNOWLEDGE

长期/非长期订阅 

长期订阅 

非长期订阅 

使用选择器 

消息过滤 

无消息过滤 

消息大小 

大量的小消息 

少量的大消息 

消息主体类型 

复杂主体类型 

简单主体类型 

传送模式(持久性/非持久性消息)

持久性消息能够在代理发生故障的情况下保证消息的传送。代理会将消息存储在持久性存储库中,直到所有预期的使用方都确认已使用消息为止。

代理处理持久性消息比处理非持久性消息要慢,原因如下:

对于队列和具有长期订户的主题而言,代理处理非持久性消息的性能要高大约 40%。 这些结果是在使用 10k 大小的消息和 AUTO_ACKNOWLEDGE 模式的情况下得到的。

使用事务

事务是一种保证,保证在一个事务会话中生成和使用的所有消息将作为一个单元进行处理或不进行处理(回滚)。

Message Queue 支持本地事务和分布式事务。

消息在事务会话中的生成或确认比在非事务会话中要慢,原因如下:

确认模式

确保可靠传送 JMS 消息的一种机制是,客户端确认使用了由 Message Queue 代理传送给它的消息。

如果在客户端尚未确认消息之前就关闭了会话,或者如果代理在处理确认之前发生了故障,代理将重新传送该消息,并设置一个 JMSRedelivered 标志。

对于非事务会话,客户端可以选择三种确认模式之一,这三种模式有其各自的性能特性:

CLIENT_ACKNOWLEDGE 模式的用法与事务的用法类似,不同之处在于:它不能保证当提供者在处理过程中发生故障时,所有确认都将一起处理。)

确认模式影响性能的原因如下:

长期订阅与非长期订阅

主题目的地的订户可以归为两类,即长期订阅的订户和非长期订阅的订户。

长期订阅的可靠性较高,但吞吐量较低,原因如下:

我们比较了两种情况下的长期订户和非长期订户的性能:10k 大小的持久性和非持久性消息。两种情况下都使用 AUTO_ACKNOWLEDGE 确认模式。我们发现只有在持久性消息情况下,才会有性能影响,使长期订阅减慢了大约 30%。

使用选择器(消息过滤)

应用程序的开发者常常需要将消息组的目标定为特定使用方。实现此任务的方法有两种:将每组消息分别指向一个唯一的物理目的地;或者是仅使用单个物理目的地,并为每个使用方注册一个或多个选择器。

选择器是一种只请求特定消息的字符串,这些消息的属性值应该与传送到特定使用方的字符串匹配。例如,选择器 NumberOfOrders >1 仅传送 NumberOfOrders 属性值为 2 或更大值的消息。

创建带有选择器的使用方会降低性能(与使用多个物理目的地相比),因为处理每个消息时需要进行额外的处理。如果使用选择器,则必须对它进行解析,以使它与将来的消息匹配。另外,路由每个消息时,都必须检索该消息的属性,并与选择器进行比较。但是,使用选择器为消息传送应用程序提供了更大的灵活性。

消息大小

消息大小会影响性能,因为从生成方客户端到代理以及从代理到使用方客户端之间必须传递更多的数据,并且对于持久性消息,必须存储更大的消息。

但是,通过将多个较小的消息组织成一个消息在一批中传送,对各个消息的路由和处理就可以变得尽可能地简单,从而获得总体性能的提高。此时,就会丢失有关各个消息的状态的信息。

在我们的测试中,比较了将消息发送至队列目的地并使用 AUTO_ACKNOWLEDGE 确认模式时,1k、10k 和 100k 大小的消息的吞吐量(KB/秒),我们发现对于 1k 的消息,非持久性消息传送比持久性消息传送快大约 50%,对于 10k 的消息快大约 20%,而对于 100k 的消息快大约 5%。消息大小对性能的影响很大,对于持久性消息和非持久性消息而言都是如此。传送 100k 的消息比传送 10k 消息快大约 10 倍,而传送 10k 消息比传送 1k 消息快大约 5 倍。

消息主体类型

JMS 支持五种消息主体类型,下面大致按复杂性顺序显示这些类型:

尽管通常情况下消息类型是由应用程序的需要所决定的,但较复杂的类型(MapMessageObjectMessage)会增加性能成本:对数据进行序列化和反序列化的成本。性能成本取决于数据的简单或复杂程度。

影响性能的消息服务因素

消息传送应用程序的性能不但受应用程序设计的影响,而且还受执行消息路由和传送的消息服务的影响。

以下各节讨论影响性能的各个消息服务因素。了解这些因素的影响对于评估消息服务以及诊断并解决在部署的应用程序中可能发生的性能瓶颈来说至关重要。

Message Queue 服务中影响性能的最重要的因素有:

以下各节讲述其中的每个因素对消息传送性能所产生的影响。

硬件

对于 Message Queue 代理和客户端应用程序而言,CPU 处理速度和可用内存都是消息服务性能的主要决定因素。 大多数软件限制都可以通过增加处理能力来消除,而添加内存则可以同时提高处理速度和容量。但是,仅通过升级硬件来克服瓶颈通常过于昂贵。

操作系统

由于不同操作系统的效率不同,因此即使硬件平台相同,性能也会各不相同。例如,操作系统使用的线程模型会对代理可以支持的并发连接数产生重要影响。在所有硬件都相同的情况下,Solaris 通常比 Linux 快,而后者通常又比 Windows 快。

Java 虚拟机 (Java Virtual Machine, JVM)

代理是受主机 JVM 支持并运行在其中的一种 Java 进程。因此,JVM 处理是决定代理路由和传送消息的速度和效率的重要因素。

特别是 JVM 的内存资源管理至关重要。必须为 JVM 分配足够的内存以适应不断增大的内存负载。另外,JVM 将定期回收未使用的内存,而这种内存回收会延迟消息的处理。JVM 内存堆越大,内存回收过程中可能遇到的延迟就越长。

连接

客户端和代理之间的连接数和速度可能影响消息服务可以处理的消息数以及消息的传送速度。

代理连接限制

对代理的所有访问都是通过连接进行的。对并发连接数的任何限制都会影响可以同时使用代理的生成方或使用方客户端的数目。

与代理的连接数通常受可用线程数的限制。可以对 Message Queue 进行配置以支持专用线程模型或共享线程模型(请参见线程池管理)。

专用线程模型的速度非常快,因为每个连接都有专用的线程,但是连接数目受可用线程数的限制(每个连接都有一个输入线程和一个输出线程)。共享线程模型对连接数不加任何限制,但是在大量连接之间共享线程会导致明显的开销和吞吐量延迟,特别是当这些连接都很繁忙时。

传输协议

Message Queue 软件允许客户端使用各种低级别的传输协议与代理进行通信。Message Queue 支持连接服务中所述的连接服务(及相应协议)。

协议的选择基于应用程序的要求(加密、可通过防火墙访问等),但是所作的选择会影响总体性能。

图 11–2 传输协议速度

显示不同传输协议的相对速度的图表。结果用文本进行说明。

我们的测试比较了两种情况下的 TCP 和 SSL 吞吐量:一个高可靠性方案(将 1k 大小的持久性消息发送至长期订阅主题目的地,并使用 AUTO_ACKNOWLEDGE 确认模式)和一个高性能方案(将 1k 大小的非持久性消息发送至非长期订阅主题目的地,并使用 DUPS_OK_ACKNOWLEDGE 确认模式)。

总的说来,我们发现在高可靠性情况下协议具有较小影响。这可能是因为在高可靠性情况下所需的持久性开销在限制吞吐量方面是比协议速度更重要的因素。另外:

消息服务体系结构

Message Queue 消息服务可以作为单个代理实现,也可以作为多个互相连接的代理实例所组成的群集实现。

随着连接到代理的客户端数量以及所传送的消息数量的不断增加,代理最终将超出资源限制(例如文件描述符、线程和内存限制)。要适应不断增加的负载,方法之一是将更多的代理实例添加到 Message Queue 消息服务,从而将客户端连接以及消息路由和传送分布到多个代理。

通常,如果客户端(特别是消息生成方客户端)均匀地分布在群集中,则这种调整最为有效。由于在群集中的代理之间传送消息涉及到开销,因此对于连接数有限或消息传送速率有限的群集而言,其性能可能会比单个代理要低。

您也可以使用代理群集来优化网络带宽。例如,您可能希望在群集内的一组远程代理之间使用低速的长途网络链路,而在客户端与其各自的代理实例之间使用高速链接进行连接。

有关群集的详细信息,请参见第 9 章,使用代理群集

代理限制和行为

代理可能需要处理的消息吞吐量是代理所支持的消息传送应用程序的使用模式的一个函数。但是,代理在以下资源上有限:内存、CPU 周期等。因此,代理可能会在无响应或不稳定的位置发生崩溃。

Message Queue 消息代理具有管理内存资源并防止代理用尽内存的内部机制。这些机制包括可以配置代理或其各自物理目的地可以拥有的消息数或消息字节数的限制,以及当达到物理目的地限制时可以实施的一组行为。

通过仔细的监视和调整,这些可配置机制可以用于平衡消息的内流和外流,使得不会发生系统过载。尽管这些机制会造成开销并限制消息的吞吐量,但它们可以维护操作的完整性。

数据存储库性能

Message Queue 既支持基于文件的持久性模块,也支持基于 JDBC 的持久性模块。基于文件的持久性使用单独的文件存储持久性数据。基于 JDBC 的持久性使用 Java 数据库连接 (Java Database Connectivity, JDBC™) 接口,并需要符合 JDBC 的数据存储库。基于文件的持久性通常比基于 JDBC 的持久性快;但是,某些用户对于符合 JDBC 的存储库所提供的冗余和管理控制更感兴趣。

如果是基于文件的持久性,您可以通过指定让持久性操作将内存中的状态与数据存储库同步,来最大限度地提高可靠性。这有助于消除因系统崩溃而导致的数据丢失,但代价是性能的下降。

客户端运行时环境配置

Message Queue 客户端运行时环境提供客户端应用程序及其与 Message Queue 消息服务的接口。它支持客户端向物理目的地发送消息以及接收来自这些目的地的消息所需的所有操作。客户端运行时环境是可配置的(通过设置连接工厂属性值),您可以控制其行为的各个方面(例如连接流度量、使用方流限制和连接流限制),从而提高性能和消息吞吐量。有关这些功能和用来配置这些功能的属性的详细信息,请参见客户端运行时环境消息流调整

调整配置以提高性能

以下各节讲述配置调整如何影响性能。

系统调整

以下各节讲述您可以对操作系统、JVM 和通信协议所做的调整。

Solaris 调整:CPU 利用率、分页/交换/磁盘 I/O

有关对操作系统的调整,请参见系统文档。

Java 虚拟机调整

默认情况下,代理使用大小为 192MB 的 JVM 堆。这对于较大的消息负载来说通常太小,应该增大。

当代理快要耗尽 Java 对象使用的 JVM 堆空间时,它将使用各种技术(如流控制和消息交换)来释放内存。在极端情况下,代理甚至关闭客户端连接以释放内存并减少消息内流。所以最好将最大 JVM 堆空间设置得足够大,以避免这种情况。

但是,与系统的物理内存相比,如果最大 Java 堆空间设置过大,代理将继续增大 Java 堆空间,直至整个系统耗尽内存。这会导致性能的降低、不可预计的代理崩溃和/或影响系统中运行的其他应用程序和服务的行为。通常,需要有足够的物理内存以供操作系统和其他应用程序在计算机上运行。

总的说来,好的方法是:估算正常和峰值系统内存容量,并配置 Java 堆大小,使其足以提供良好性能,但同时不应过大,以免引起系统内存问题。

要更改代理的最小和最大堆大小,请在启动代理时使用 -vmargs 命令行选项。例如:

/usr/bin/imqbrokerd -vmargs "-Xms256m -Xmx1024m"

此命令将启动 Java 堆大小设置为 256MB,将最大 Java 堆大小设置为 1GB。

在任何情况下,都应当通过检查代理的日志文件或通过使用 imqcmd metrics bkr -m cxn 命令来验证设置。

调整传输协议

选择了符合应用程序需要的协议后,基于该协议进行其他调整可能有助于提高性能。

可以使用下面三个代理属性修改协议的性能:

对于 TCP 和 SSL 协议,这些属性会影响客户端与代理之间的消息传送速度。对于 HTTP 和 HTTPS 协议,这些属性会影响 Message Queue 隧道 Servlet(在 Web 服务器上运行)与代理之间的消息传送速度。对于 HTTP/HTTPS 协议,还有其他可以影响性能的属性(请参见 HTTP/HTTPS 调整)。

协议调整属性将在以下各节中讲述。

nodelay

nodelay 属性影响给定协议的 Nagle 算法(TCP/IP 上的 TCP_NODELAY 套接字级选项的值)。Nagle 算法用于提高使用慢速连接(例如广域网 (Wide-area Network, WAN))的系统上的 TCP 性能。

如果使用了此算法,TCP 将通过把多个数据捆绑为较大的包来尝试防止将多个小块数据发送到远程系统。如果写入套接字中的数据没有填满需要的缓冲区大小,协议将延迟发送包,直到缓冲区被填满,或者经过了特定的延迟时间为止。填满了缓冲区或者发生了超时后,包将被发送。

对于大多数消息传送应用程序,如果包发送过程中没有延迟(Nagle 算法未启用),则性能是最佳的。这是因为客户端与代理之间的大多数交互都是请求/响应交互:客户端向代理发送数据包,并等待响应。例如,典型的交互包括:

对于这些交互,大多数包都比缓冲区大小要小。这意味着如果使用 Nagle 算法,代理会在向使用方发送响应之前延迟几毫秒。

但是,在连接较慢以及不需要代理响应的情况下,Nagle 算法可以提高性能。例如,客户端发送非持久性消息或者客户端确认未被代理确认(DUPS_OK_ACKNOWLEDGE 会话)就属于这样的情况。

inbufsz/outbufsz

inbufsz 属性用于在读取来自套接字的数据的输入流上设置缓冲区大小。同样,outbufsz 用于设置代理用来将数据写入套接字的输出流的缓冲区大小。

通常,这两个参数都应该设置为比收发的平均包稍大的值。一个很好的经验是将这些属性值设为平均包的大小再加上 1k(舍入为最接近的 k 值)。例如,如果代理正在接收主体大小为 1k 的包,则该包的总体大小(消息主体+标题+属性)约为 1200 字节;大小为 2k(2048 字节)的 inbufsz 可以提供合理的性能。增大 inbufszoutbufsz(使其大于该值)可以稍微提高性能,但这样会增加每个连接所需的内存。

HTTP/HTTPS 调整

除了前面两节讨论的一般属性之外,HTTP/HTTPS 的性能还受到客户端向作为 Message Queue 隧道 Servlet 宿主的 Web 服务器发出 HTTP 请求的速度的限制。

Web 服务器可能需要优化,以处理单个套接字上的多个请求。在 JDK 1.4 版及更高版本中,与 Web 服务器的 HTTP 连接会一直保持活动状态(与 Web 服务器的套接字保持打开状态),以尽量减少 Web 服务器在处理多个 HTTP 请求时使用的资源。如果使用 JDK 1.4 版的客户端应用程序的性能比运行早期 JDK 版本的同一应用程序要低,则可能需要调整 Web 服务器的 keep-alive 配置参数以提高性能。

除了这样的 Web 服务器调整之外,您还可以调整客户端轮询 Web 服务器的频率。HTTP 是一种基于请求的协议。这意味着使用基于 HTTP 的协议的客户端需要定期检查 Web 服务器,以查看是否有消息在等待。imq.httpjms.http.pullPeriod 代理属性(以及相应的 imq.httpsjms.https.pullPeriod 属性)指定 Message Queue 客户端运行时环境轮询 Web 服务器的频率。

如果 pullPeriod 值为 -1(默认值),客户端运行时环境将在前一个请求返回后立即轮询服务器,从而最大限度地提高各个客户端的性能。结果,每个客户端连接都会在 Web 服务器中独占一个请求线程,这样可能会耗费 Web 服务器资源。

如果 pullPeriod 值为正数,客户端运行时环境将定期向 Web 服务器发送请求,以查看是否有挂起的数据。在这种情况下,客户端不会独占 Web 服务器中的请求线程。因此,如果有大量客户端在使用 Web 服务器,您可以通过将 pullPeriod 设为正值来节省 Web 服务器资源。

调整基于文件的持久性存储库

有关调整基于文件的持久性存储库的信息,请参见持久性服务

代理调整

以下各节介绍为了提高性能可以对代理属性进行的调整。

内存管理:提高代理在负载下的稳定性

内存管理可以分别在各个目的地上配置,也可以在系统范围级别内(对于所有目的地)配置。

使用物理目的地限制

有关物理目的地限制的信息,请参见第 6 章,管理物理目的地

使用系统范围的限制

如果消息生成方的数目超过消息使用方的数目,则消息可能在代理中堆积。代理包含限制生成方以及在内存很低的情况下将消息交换出活动内存的机制,但最好还是对代理可以保持的消息总数和消息字节总数进行严格限制。

可以通过设置 imq.system.max_countimq.system.max_size 代理属性来控制这些限制。

例如:

imq.system.max_count=5000

上面定义的值表示代理最多只能保存 5000 条未传送/未确认的消息。如果发送了其他消息,它们将被代理拒绝。如果消息是持久性的,当生成方尝试发送该消息时,会收到一个异常。如果消息是非持久性的,代理将在不给出任何提示的情况下丢弃该消息。

如果在发送消息的过程中返回了异常,客户端应该暂停片刻,然后再次尝试发送。(请注意,异常绝不会是由于代理未能接收消息而引发的;所引发的异常都是由发送方客户端检测到的。)

多使用方队列性能

多队列使用方处理队列目的地中的消息的效率取决于下列可配置的队列目的地属性:

要达到最优的消息吞吐量,必须有足够数量的活动使用方以适应队列的消息生成速率,并且队列中的消息必须以最大化使用速率的方式路由和传送给活动使用方。Sun Java SystemTM Message Queue Technical Overview中介绍了在多个使用方之间平衡消息传送的一般机制。

如果消息在队列中堆积,这可能是因为没有足够的活动使用方来处理消息负载。也可能是每批传送给使用方的消息太多,导致消息在使用方堆积。例如,如果每批的大小 (consumerFlowLimit) 太大,某个使用方就可能会收到一个队列中的所有消息,而其他活动使用方则一个也没有收到。如果使用方速度特别快,这也不会成为问题。

但是如果使用方相对较慢,而您又希望将消息均匀地分配给它们,则需要将每一批的大小减小。每一批的大小越小,将消息传送到使用方所需的开销就越多。但是,对于较慢的使用方,使用较小的批大小通常能获得网络性能的提升。

客户端运行时环境消息流调整

在本节中将会讨论影响性能的流控制行为(请参见客户端运行时环境配置)。这些行为可配置为连接工厂受管理对象的属性。有关设置连接工厂属性的信息,请参见第 8 章,管理受管理对象

消息流度量

客户端收发的消息(有效负荷消息)以及 Message Queue 控制消息通过同一客户端-代理连接传递。如果控制消息(例如代理确认)被有效负荷消息的传送阻挡,则控制消息的传送会发生延迟。为防止此类拥塞,Message Queue 会度量通过连接进行的有效负荷消息流。

有效负荷消息是成批的(由连接工厂属性 imqConnectionFlowCount 指定),以便只传送数目设定的一组消息。传送完一批后,将暂停有效负荷消息的传送,而只传送暂挂的控制消息。当另一批有效负荷消息传送后,接着又传送暂挂的控制消息,如此循环往复。

如果客户端执行的是需要代理作出大量响应的操作,则 imqConnectionFlowCount 应保持较低的值:例如,当客户端使用的是 CLIENT_ACKNOWLEDGE AUTO_ACKNOWLEDGE 模式、持久性消息、事务或队列浏览器,或者正在添加或删除使用方时。从另一方面来说,如果客户端仅在使用 DUPS_OK_ACKNOWLEDGE 模式的连接上有简单的使用方,则可以增大 imqConnectionFlowCount 而不会降低性能。

消息流限制

在遇到本地资源(例如内存)限制之前,存在 Message Queue 客户端运行时环境可以处理的有效负荷消息数限制。如果达到了此限制,性能将受影响。因此,Message Queue 允许您限制每个使用方(或每个连接)能够通过连接传送和能够在客户端运行时环境中缓冲以等待使用的消息数。

使用方流限制

当传送到客户端运行时环境的有效负荷消息数超过任意使用方的 imqConsumerFlowLimit 值时,将停止传送该使用方的消息。仅当该使用方的未使用消息数下降至低于 imqConsumerFlowThreshold 设置的值时才会恢复消息传送。

下例说明了如何使用这些限制,以主题使用方的默认设置为例:

imqConsumerFlowLimit=1000
imqConsumerFlowThreshold=50

创建使用方后,代理将向此使用方传送第一批 1000 条消息(前提是有这么多),中间不会暂停。发送 1000 条消息后,代理将停止传送,除非客户端运行时环境要求更多消息。客户端运行将保存这些消息,直到应用程序处理它们为止。在要求代理发送下一批消息之前,客户端运行时环境会允许应用程序使用至少 50% (imqConsumerFlowThreshold) 的消息缓冲区容量(即 500 条消息)。

在同等情况下,如果阈值为 10%,则客户端运行时环境会等待应用程序使用至少 900 条消息,然后才会要求发送下一批消息。

下一批消息的大小按如下计算:

imqConsumerFlowLimit - (缓冲区中当前暂挂的消息数)

因此,如果 imqConsumerFlowThreshold 为 50%,则下一批的大小会在 500 和 1000 之间波动,这取决于应用程序处理消息的速度。

如果 imqConsumerFlowThreshold 设置得过高(接近 100%),代理就会发送较小的分批消息,这样会降低消息的吞吐量。如果该值设置过低(接近 0%),则客户端可以在代理传送下一组消息之前处理完剩余的缓冲消息,从而再次导致消息吞吐量下降。通常,除非您有特别的性能或可靠性考虑,否则不需要更改 imqConsumerFlowThreshold 属性的默认值。

基于使用方的流控制(特别是 imqConsumerFlowLimit)是管理客户端运行时环境中的内存的最好方法。通常,根据客户端应用程序的不同,您应该知道在任意连接上需要支持的使用方数、消息的大小以及可用于客户端运行时环境的内存总量。

连接流限制

但是在某些客户端应用程序中,使用方数量可能是不确定的,这取决于最终用户所作的选择。在这些情况下,您仍可以使用连接级流限制来管理内存。

连接级流控制可以限制针对一个连接上的所有使用方而缓冲的消息总数。如果该数目超过了 imqConnectionFlowLimit 的值,则通过该连接进行的消息传送将停止,直到消息总数降到连接限制以下为止。(只有当 imqConnectionFlowLimitEnabled 设置为 true 时,imqConnectionFlowLimit 属性才会启用。)

在会话中排队的消息数是使用该会话的消息使用方数量以及每个使用方的消息负载的函数。如果客户端在生成或使用消息时表现出延迟,您通常可以通过下列操作来提高性能:重新设计应用程序,以便在更大数量的会话之间分布消息生成方和使用方,或者在更大数量的连接之间分布会话。

第 12 章 问题疑难解答

本章介绍了如何理解和解决以下问题:

出现问题时,检查所安装 Message QueueTM 软件的版本号会很有帮助。可以使用版本号来确保目前正在使用的文档版本与软件版本相匹配。向 Sun 报告问题时,也需要用到版本号。要检查版本号,请执行以下命令:

imqcmd -v

客户端无法建立连接

症状:

可能的原因:

可能的原因:客户端应用程序不关闭连接,导致连接数超出资源限制。

确认问题的起因:列出代理的所有连接:

imqcmd list cxn

输出结果将列出所有连接以及发起每个连接的主机,从而显示具体是哪些客户端的打开连接数超出限制。

解决此问题:重写有问题的客户端,以关闭未使用的连接。

可能的原因:代理未运行或者网络连接有问题。

确认问题的起因:

解决此问题:

可能的原因:连接服务处于非活动状态或者已暂停。

确认问题的起因:检查所有连接服务的状态:

imqcmd list svc

如果某个连接服务的状态显示为 unknownpaused,客户端将无法使用该服务建立连接。

解决此问题:

可能的原因:相对于所需的连接数而言,可用线程数不足。

确认问题的起因:在代理日志中检查下面的条目:

警告 [B3004]:服务上没有可以用来处理新连接的线程...关闭新连接。

此外,请检查连接服务上的连接数以及当前使用的线程数(使用以下格式之一):

imqcmd query svc -n serviceName imqcmd metrics svc -n serviceName -m cxn

每个连接都需要两个线程:一个用于传入消息,另一个用于传出消息(请参见线程池管理)。

解决此问题:

可能的原因:相对于 Solaris 或 Linux 平台上需要的连接数而言,文件描述符不足。

有关此问题的详细信息,请参见设置文件描述符限制

确认问题的起因:在代理日志中查找与下面显示的条目类似的条目:

打开了太多文件

解决此问题:增大文件描述符限制,如 ulimit 手册页中所述。

可能的原因:TCP 后备队列限制了可以同时建立的新连接请求的数目。

TCP 后备队列限制可以同时存储在系统后备队列 (imq.portmapper.backlog) 中的连接请求数,超过此限制后,端口映射器将拒绝额外的请求。(在 Windows 平台上,有一种硬编码的后备队列限制:Windows 台式机限制为 5,而 Windows 服务器限制为 200。)

出于后备队列限制而拒绝请求通常是一种由于同时连接请求数过多而导致的瞬态现象。

确认问题的起因:检查代理日志。首先,检查代理是否在接受某些连接的同时拒绝其他连接。其次,检查说明拒绝连接原因的消息。如果找到此类消息,则说明问题可能不是由 TCP 后备队列引起的,因为代理不记录由于 TCP 后备队列而引起的连接拒绝事件。如果记录了一些成功连接,但未记录任何连接拒绝事件,则问题可能是由 TCP 后备队列引起的。

解决此问题:

可能的原因:操作系统限制了并发连接数。

Windows 操作系统许可证对支持的并发远程连接数进行了限制。

确认问题的起因:检查是否有可用于连接的足够线程(使用 imqcmd query svc),并检查您的 Windows 许可协议的条款。如果您可以从本地客户端建立连接,但不能从远程客户端建立连接,则操作系统的限制可能就是问题的起因。

解决此问题:

可能的原因:对用户的验证或授权失败。

验证可能因为以下原因失败:

确认问题的起因:检查代理日志中的条目,查看是否有 Forbidden 错误消息。此消息指明存在验证错误,但不会指明该错误的原因。

解决此问题:

连接的吞吐量太低

症状:

可能的原因:

可能的原因:网络连接或 WAN 太慢。

确认问题的起因:

解决此问题:升级网络链路。

可能的原因:与 TCP 相比,连接服务协议本身就慢。

例如,基于 SSL 的协议或基于 HTTP 的协议要比 TCP 慢(请参见传输协议)。

确认问题的起因:如果您使用的是基于 SSL 或基于 HTTP 的协议,请尝试使用 TCP,然后比较传送时间。

解决此问题:应用程序要求通常会指定要使用的协议,因此除了按调整传输协议中所述尝试调整协议之外,您几乎无法执行任何其他操作。

可能的原因:连接服务协议未进行优化调整。

确认问题的起因:尝试调整协议,确定是否发生了变化。

解决此问题:尝试按调整传输协议中所述调整协议。

可能的原因:消息太大,以致于占用了过多的带宽。

确认问题的起因:尝试使用较小的消息运行基准测试程序。

解决此问题:

可能的原因:使连接吞吐量变低的可能原因也就是消息传送过程中某个步骤的瓶颈。

确认问题的起因:如果上述任何一条似乎都不是造成连接吞吐量变低的原因,请参见影响性能的因素以了解其他可能的瓶颈,并检查与以下问题相关的症状:

解决此问题:请遵循上述有关疑难解答的各节中所提供的问题解决原则。

客户端无法创建消息生成方

症状:

可能的原因:

可能的原因:物理目的地被配置为仅允许有限数目的生成方。

限制某个物理目的地所支持的生成方 (maxNumProducers ) 数目是避免消息在该物理目的地上堆积的方法之一。

确认问题的起因:检查物理目的地:

imqcmd query dst

(请参见显示有关物理目的地的信息)。输出结果将显示当前的生成方数目以及 maxNumProducers 的值。如果这两个值相同,则说明生成方的数目已达到所配置的限制。如果新的生成方被代理拒绝,代理将返回异常

ResourceAllocationException [C4088]:已达到 JMS 目的地限制

且在代理日志中生成如下条目:

[B4183]:无法将生产方添加到目的地

解决此问题:增加 maxNumProducers 属性的值(请参见更新物理目的地属性)。

可能的原因:由于访问控制属性文件中的设置,用户未获得创建消息生成方的授权。

确认问题的起因:如果新的生成方被代理拒绝,代理将返回异常

JMSSecurityException [C4076]:客户端没有在目的地上创建生成方的权限

且在代理日志中记录以下条目:

[B2041]:目的地上的生成方被拒绝 [B4051]:禁用 guest

解决此问题:更改访问控制属性,允许用户生成消息(请参见对物理目的地的访问控制)。

消息的生成过程延迟或速度减慢

症状:

可能的原因:

可能的原因:代理上堆满了后备队列,使得消息生成方的执行速度变慢。

堆满后备队列的代理将消息堆积在代理内存中。当物理目的地内存中的消息数或消息字节数达到配置的限制时,代理会尝试根据指定的限制行为来节省内存资源。以下限制行为会使消息生成方速度减慢:

同样,如果代理范围的内存(对于所有物理目的地)中消息数或消息字节数达到配置的限制,代理将尝试通过拒绝最新的消息来节省内存资源。另外,如果达到了系统内存限制(由于物理目的地或代理范围限制设置不正确),代理将采取愈加严格的操作来防止内存过载。这些操作包括限制消息生成方。

确认问题的起因:如果某个消息因为达到了配置的消息限制而被代理拒绝,代理将返回异常

JMSException [C4036]:发生服务器错误

且在代理日志中生成以下条目:

[B2011]:存储来自 IMQconn 的 JMS 消息失败

随后又产生一条消息表明已达到内存限制:

[B4120]:无法在目的地 destName 上存储消息,因为会超出 maxNumMsgs 的容量。

如果超出的消息限制是在物理目的地上,或

[B4024]:已经超出目前系统中的最大消息数,正在拒绝消息。

如果消息限制是代理范围的。

通常,您可以在发生拒绝之前按如下方式检查消息限制情况:

解决此问题:

可能的原因:代理无法将持久性消息保存到数据存储库中。

如果代理无法访问数据存储库或者无法将持久性消息写入数据存储库,则生成方客户端将受阻。如前所述,如果达到了目的地或代理范围的消息限制,也会发生这种情况。

确认问题的起因:如果代理无法写入数据存储库,它将在代理日志中生成以下条目之一:

[B2011]:存储来自 connectionID 的 JMS 消息失败[B4004]:无法持续消息 messageID

解决此问题:

可能的原因:代理的确认超时时间太短。

由于连接太慢或代理反应迟缓(由于 CPU 占用率太高或者内存资源不足导致),代理用于确认收到持久性消息的时间比连接工厂的 imqAckTimeout 属性值所允许的时间要长。

确认问题的起因:如果超出了 imqAckTimeout 值,代理将返回异常

JMSException [C4000]:包确认失败

解决此问题:更改 imqAckTimeout 连接工厂属性的值(请参见可靠性和流控制)。

可能的原因:生成方客户端遇到了 JVM 限制。

确认问题的起因:

解决此问题:调整 JVM(请参见Java 虚拟机调整)。

消息堆积

症状:

要查看消息是否在堆积,请检查代理中的消息数或消息字节数如何随时间的推移而改变,并与配置的限制进行比较。首先检查配置的限制:

imqcmd query bkr


注 –

imqcmd metrics bkr 子命令不会显示此信息。


然后检查每个目的地中的消息堆积情况。

imqcmd list dst

要检查消息是否已超出配置的目的地或代理范围的限制,请在代理日志中检查如下条目:

[B2011]:存储来自 的 JMS 消息失败。

此条目后面接有另一个标识已超出限制的条目。

可能的原因:

可能的原因:主题目的地上有非活动的长期订阅。

如果长期订阅是非活动的,则消息会存储在目的地中,直到相应的使用方变为活动状态且能够使用这些消息为止。

确认问题的起因:检查每个主题目的地上的长期订阅的状态:

imqcmd list dur -d destName

解决此问题:

可能的原因:队列中可以使用消息的使用方太少。

如果消息可以传送到的活动使用方太少,队列目的地可能会随着消息的堆积而堆满了后备队列。只要有下列任何原因,都会发生此情况:

确认问题的起因:要确定使用方不可用的原因,请检查目的地上活动使用方的数目:

imqcmd metrics dst - n destName -t q -m con

解决此问题:根据使用方不可用的原因,

可能的原因:消息使用方的处理速度太慢,跟不上消息生成方的速度。

在这种情况下,主题的订阅者或队列的接收者使用消息的速度要比生成方发送消息的速度慢。有一个或多个目的地因为这种不平衡而堆满了消息。

确认问题的起因:检查消息流入和流出代理的速率:

imqcmd metrics bkr -m rts

然后检查每个单独目的地的流速:

imqcmd metrics bkr -t destType -n destName - m rts

解决此问题:

可能的原因:客户端确认处理减慢了消息的使用。

有两个因素影响客户端确认处理:

确认问题的起因:

解决此问题:

可能的原因:代理无法适应生成消息的速度。

在这种情况下,消息流入代理的速度比代理可以将它们路由并发送到使用方的速度要快。代理的迟缓可能由下列任一或全部限制所导致:

确认问题的起因:检查有无其他可能的原因导致此问题。

解决此问题:

可能的原因:客户端代码缺陷:使用方不确认消息。

消息会保留在目的地中,直到消息所发送到的所有使用方都进行了确认为止。如果客户端没有确认已使用消息,则该消息会在目的地中堆积,而不会被删除。

例如,客户端代码可能存在以下缺陷:

确认问题的起因:首先检查本节中列出的其他所有可能的原因。其次,使用以下命令列出目的地:

imqcmd list dst

请注意 UnAcked 标题下列出的消息数目是否与目的地中的消息数目相同。此标题下的消息已发送到使用方但未得到确认。如果此数目与消息总数相同,则说明代理已发送所有消息,正在等待确认。

解决此问题:请求应用程序开发者帮助调试此问题。

代理吞吐量呈间歇性

症状:

可能的原因:

可能的原因:代理的内存资源非常低。

由于目的地和代理限制设置不当,代理采取了越来越严格的措施以防止内存过载,这样就导致代理变得非常迟缓,直到堆积的消息得到清除为止。

确认问题的起因:在代理日志中检查内存低的情况:

[B1089]:内存不足,代理正在尝试释放资源

该情况后面会接有一个描述新内存状态和已用内存总量的条目。另外请检查 JVM 堆中的可用内存:

imqcmd metrics bkr -m cxn

当总 JVM 内存接近 JVM 内存最大值时,可用内存就会很低。

解决此问题:

可能的原因:正在发生 JVM 内存回收(垃圾收集)。

内存回收会定期清扫整个系统,以释放内存。发生此操作时,所有的线程都会阻塞。要释放的内存量以及 JVM 堆的大小越大,因内存回收而导致的延迟就越长。

确认问题的起因:监视计算机上的 CPU 使用率。发生内存回收时,CPU 使用率会下降。

另外,使用以下命令行选项启动代理:

- vmargs -verbose:gc

其标准输出指明发生内存回收的时间。

解决此问题:在多个 CPU 的计算机中,将内存回收设置为并行发生:

-XX:+UseParallelGC=true

可能的原因:JVM 使用实时编译器来提高性能。

确认问题的起因:检查有无其他可能的原因导致此问题。

解决此问题:让系统运行一段时间,性能应该会有所改善。

消息无法到达使用方

症状:

可能的原因:

可能的原因:限制行为导致消息在代理上被删除。

如果目的地内存中的消息数或消息字节数达到了配置限制,代理将尝试节省内存资源。当达到限制时,代理将采用下列三个可配置的行为,从而导致消息丢失:

确认问题的起因:检查停用消息队列,如停用消息队列包含消息中所述。具体地说,是使用“消息的数目或者其大小超出目的地限制”中的说明。查找 REMOVE_OLDEST REMOVE_LOW_PRIORITY 原因。

解决此问题:增加目的地限制。例如:

imqcmd update dst -n MyDest - o maxNumMsgs=1000

可能的原因:消息超时值即将到期。

代理将删除超时值已过期的消息。如果目的地上完全堆满了消息,生存时间值过短的消息将被删除。

确认问题的起因:使用 QBrowser 演示应用程序来查看停用消息队列内容并查看消息是否超时。要了解 QBrowser 演示程序特定于平台的位置,请参见附录 A, Message QueueTM 数据在特定平台上的位置并查看“示例应用程序和位置”表。

下面是 Windows 平台中的一个调用示例:

cd \MessageQueue3\demo\applications\qbrowser java QBrowser

QBrowser 主窗口出现后,选择队列名称 mq.sys.dmq,然后单击 "Browse"。将出现如下所示的列表:

QBrowser 显示 mq.sys.dmq 的消息。每条消息都包括编号、时间戳、类型、模式以及优先级。

双击消息可显示该消息的详细信息:

消息详细信息窗口。顶部窗格显示消息;中间窗格显示其属性;底部窗格包含消息。

请注意消息的 JMS_SUN_DMQ_UNDELIVERED_REASON 属性值是否为 EXPIRED

解决此问题:联系应用程序开发者,请他们提高生存时间值。

可能的原因:时钟不同步。

如果时钟之间不同步,则代理对消息生命周期的计算可能有错误,从而导致消息超过它们的到期时间而被删除。

确认问题的起因:在代理日志文件中,查找下列任一消息:B2102B2103B2104。这些消息均报告检测到可能的时钟脉冲相位差。

解决此问题:检查您是否正在运行时间同步程序,如准备系统资源中所述。

可能的原因:使用方客户端未能在某个连接上启动消息传送。

除非客户端代码建立了连接,并在该连接上启动了消息传送,否则消息将无法传送。

确认问题的起因:检查客户端代码是否能建立连接并启动消息传送。

解决此问题:重写客户端代码,以建立连接并启动消息传送。

停用消息队列包含消息

症状:


Listing all the destinations on the broker specified by:
---------------------------------
Host         Primary Port
---------------------------------
localhost    7676
----------------------------------------------------------------------
   Name     Type    State   Producers  Consumers  Msgs
                                         Total    Count  UnAck  Avg Size
------------------------------------------------- ----------------------
MyDest      Queue  RUNNING       0          0        5      0    1177.0
mq.sys.dmq  Queue  RUNNING       0          0       35      0    1422.0
Successfully listed destinations.

在本示例中,停用消息队列 mq.sys.dmq 包含 35 条消息。

可能的原因:

可能的原因:消息的数目或者其大小超出目的地限制。

确认问题的起因:使用 QBrowser 演示应用程序来查看停用消息队列的内容。要了解 QBrowser 演示程序特定于平台的位置,请参见附录 A, Message QueueTM 数据在特定平台上的位置并查看“示例应用程序和位置”表。

下面是 Windows 平台中的一个调用示例:

cd \MessageQueue3\demo\applications\qbrowser java QBrowser

QBrowser 主窗口出现后,选择队列名称 mq.sys.dmq,然后单击 "Browse"。将会出现如前面“消息超时值即将到期”中所示的列表。双击消息可显示该消息的详细信息,如“消息超时值即将到期”中所示。

请注意下列消息属性的值:

请注意 JMS 标题下面的 JMSDestination 值,以确定消息将停用的目的地。

解决此问题:增加目的地限制。例如:

imqcmd update dst - n MyDest -o maxNumMsgs=1000

可能的原因:代理时钟和生成方时钟不同步。

确认问题的起因:使用 QBrowser 应用程序来查看停用消息队列中各消息的详细信息。检查 JMS_SUN_DMQ_UNDELIVERED_REASON 的值,查找原因为 EXPIRED 的消息。

在代理日志文件中,查找下列任一消息:B2102 B2103B2104。这些消息均报告检测到可能的时钟脉冲相位差。

解决此问题:检查您是否正在运行时间同步程序,如准备系统资源中所述。

可能的原因:消息超时前,使用方未接收到消息。

确认这是否就是问题的起因:使用 QBrowser 应用程序来查看停用消息队列中各消息的详细信息。检查 JMS_SUN_DMQ_UNDELIVERED_REASON 的值,查找原因为 EXPIRED 的消息。

检查目的地中是否有任何使用方。例如:

imqcmd query dst -t q -n MyDest

检查列出的“当前活动使用方”值。如果有活动使用方,则下面的某一项为真:

解决此问题:请求应用程序开发者提高消息的生存时间值。

可能的原因:相对使用方数目而言,生成方太多。

确认问题的起因:使用 QBrowser 应用程序来查看停用消息队列中各消息的详细信息。检查 JMS_SUN_DMQ_UNDELIVERED_REASON 的值。如果原因是 REMOVE_OLDESTREMOVE_LOW_PRIORITY,请使用 imqcmd query dst 命令来检查目的地中的生成方和使用方的数目。如果生成方的数目超过使用方的数目,则生成率可能会远远超出使用率。

解决此问题:添加更多的使用方客户端,或者使用如下所示的命令,将目的地限制行为设置为 FLOW_CONTROL(该限制行为通过使用率来控制生成率):

imqcmd update dst -n myDst -t q -o consumerFlowLimit=FLOW_CONTROL

可能的原因:生成方比使用方的速度快。

确认问题的起因:要确定较慢的使用方是否会导致生成方的速度降低,请使用如下所示的命令,将目的地限制行为设置为 FLOW_CONTROL(该限制行为通过使用率来控制生成率):

imqcmd update dst -n myDst -t q -o consumerFlowLimit=FLOW_CONTROL

使用如下所示的命令,使用度量来检查目的地的输入和输出:

imqcmd metrics dst - n myDst -t q -m rts

在度量输出中,检查以下值:

由于流控制使生成与使用协调一致,因此请注意生成是否减慢或停止。如果生成减慢或停止,则说明生成方和使用方的处理速度不一致。也可以使用 imqcmd list dst 命令,检查未确认的 (UnAcked) 发送消息的数目。如果未确认的消息数目小于目的地大小,则表明目的地尚有额外的容量,它受到客户端流控制的抑制。

解决此问题:如果生成率始终高于使用率,可以考虑有规律地使用流控制以使系统保持协调一致。此外,使用后面各节的内容,考虑并尝试消除下列可能的因素:

可能的原因:使用方太慢。

确认问题的起因:使用度量来确定生成和使用的速率,如前面“生成方比使用方的速度快”中所述。

解决此问题:

可能的原因:客户端不提交消息。

确认问题的起因:与应用程序开发者进行确认以查明应用程序是否使用事务。如果应用程序使用事务,则按如下所示列出活动事务:

imqcmd list txn

下面是一个命令输出示例:


----------------------------------------------------------------------
Transaction ID       State    User name  # Msgs/# Acks   Creation time
----------------------------------------------------------------------
6800151593984248832  STARTED  guest           3/2     7/19/04 11:03:08 AM

请注意消息和确认的数目。如果消息的数目很高,则生成方可能正在发送个别的消息,而未能提交事务。代理在收到提交之前,无法路由并传送该事务的消息。如果确认的数目很高,则使用方可能正在发送个别消息的确认,而未能提交事务。代理在收到提交之前,无法删除该事务的确认。

解决此问题:联系应用程序开发者以修复编码错误。

可能的原因:使用方未能确认消息。

确认问题的起因:联系应用程序开发者以确定应用程序使用的是基于系统的确认还是基于客户端的确认。如果应用程序使用基于系统的确认,则跳过本节;如果应用程序使用基于客户端的确认 (CLIENT_ACKNOWLEDGE),请先使用如下命令减少客户端中存储的消息数:

imqcmd update dst -n myDst -t q -o consumerFlowLimit=1

其次,确定是因为代理由于使用方速度慢而缓冲消息,还是因为使用方处理消息的速度很快但未对其进行确认。使用以下命令列出目的地:

imqcmd list dst

在提供用户名和密码后,将显示类似以下内容的输出:


Listing all the destinations on the broker specified by:
---------------------------------
Host         Primary Port
---------------------------------
localhost    7676
----------------------------------------------------------------------
   Name     Type    State   Producers  Consumers  Msgs
                                         Total    Count  UnAck  Avg Size
------------------------------------------------ -----------------------
MyDest      Queue  RUNNING       0          0        5    200    1177.0
mq.sys.dmq  Queue  RUNNING       0          0       35      0    1422.0
Successfully listed destinations.

未确认数值表示代理已发送且正在等待确认的消息数。如果此数值较高或不断增加,则说明代理正在发送消息,因此不等待速度较慢的使用方。还说明使用方未确认消息。

解决此问题:联系应用程序开发者以修复编码错误。

可能的原因:长期使用方处于非活动状态。

确认问题的起因:使用以下命令格式查看主题的长期订户:

imqcmd list dur -d topicName

解决此问题:

可能的原因:发生意外的代理错误。

确认问题的起因:使用 QBrowser 对消息进行检查,如前面“生成方比使用方的速度快”中所述。如果 JMS_SUN_DMQ_UNDELIVERED_REASON 的值是 ERROR,则说明代理发生错误。

解决此问题: