WebSphere MQ 最佳实践 Top 15

许多文章和书籍提供了有关设计消息队列并将其集成到应用程序中的很好建议。本文通过列举有关使用 WebSphere MQ 来实现消息队列的 15 个(或得到如此广泛认可的)最佳实践,从而简化了这个迷宫般的问题。本文描述有关设计、构建、运行和维护 WebSphere MQ 解决方案的最常见最佳实践,以便实现 WebSphere MQ 的全部好处。

Peyling Hsieh, IBM 业务合作伙伴创新中心技术顾问, IBM

Peyling Hsieh 是位于马萨诸塞州沃尔瑟姆的 IBM 业务合作伙伴创新中心的技术顾问。她拥有计算机科学硕士学位,并且已经在 IBM 工作了 19 年:其中八年时间从事 AIX/SP2 上 C/C++ /Java 开发,另外 11 年时间帮助 IBM 业务合作伙伴实现基于 IBM 技术的应用程序。她目前在帮助 IBM 业务合作伙伴对 IBM 硬件和中间件平台上的应用程序进行移植、迁移和性能测试。她擅长的领域包括 WebSphere Application Server、WebSphere MQ 和 Retail on Demand Store Integration Framework。



Michael Ryan, NY Area Software Business Unit – NY Financial 的软件 IT 架构师, IBM

Michael Ryan 是 IBM NY Area Software Business Unit 的一名软件 IT 架构师。他的角色是使用可重复的体系结构方法和辅助技能,将客户计划和挑战转换为完整的软件体系结构。在担任当前职务之前,Michael 是 EAI Practice of IBM Global Business Services 咨询部门的一名高级 IT 架构师。在他的九年 GBS 工作期间,他为 20 多家客户提供过 EAI 应用程序开发、设计和体系结构方面的服务,这些客户主要分布在金融服务业。



Chris Kline, IBM Global Services 的 WebSphere MQ 支持部门的中间件架构师, IBM

Chris Kline 是 IBM 的服务交付组织 Integrated Technology Delivery 的一名 IT 架构师。他拥有信息系统管理方面的硕士学位,自从 2001 年以来一直在为 IBM 工作,负责为 IBM 的一些最大客户提供 WebSphere 产品支持。Chris 喜欢构建工具来自动化各种中间件产品的管理和维护,并且已提交了许多相关专利申请。他是 UNIX 和 Linux 上的 WebSphere MQ 产品的主题专家。



2008 年 10 月 06 日

引言

IBM® WebSphere® MQ(以下称为 MQ)是 IBM 的面向消息的中间件产品。它支持异构系统上的独立和可能非并发的应用程序彼此通信。MQ 在 80 多个不同的平台和环境中受到支持。

MQ 的优点之一是对于多样性的客户环境和数据传输需要,它能够变得高度可配置和可自定义。然而,这个优点可能使配置糟糕的系统泛滥成灾,这样的系统不支持将来的扩展、不断变化的开发标准和协议,以及可靠的安全性。本文描述有关设计、构建、运行和维护 MQ 解决方案的最常见最佳实践,以便实现 MQ 的全部好处。务必记住,并非所有的建议都适合于所有情形,并且这些建议是作为指导原则而不是作为硬性规则来提供的。大型的复杂企业可能通常有背离这些建议的充分理由。本文是基于 MQ V6 编写的,并假设您具备 MQ 的基础知识。

MQ 使得应用程序设计人员能够构造长期有效的体系结构。其通用性、灵活性以及广泛的实现和环境,使得描述能涵盖所有情况的过程非常困难。本最佳实践列表应该使架构师、系统管理员和应用程序开发人员能够避免常见的错误,并在他们的解决方案中最优地利用 MQ。该列表是按照解决方案的设计、构建、运行和维护这四个阶段来进行组织的。

设计

对队列管理器和 MQ 对象使用短名称

有时,仅只是给队列命名也会充满挑战。在其他情况下,您已经创建了如此多的队列和其他对象,以致您的命名约定不再有效,或者没有您预期的那样具有描述性。一般来讲,除了通道名称不能超过 20 个字符以外,MQ 对象的名称最多可以有 48 个字符。您可以使用大写和小写的字母 A-Z、数字 0-9、下划线 (_)、句点 (.) 和两个特殊字符:正斜杠 (/) 和百分号 (%)。如果使用了两个特殊字符中的任何一个,则必须将名称包括在双引号中。

除了一般规则以外,下面是一些建议用于对队列管理器和 MQ 对象命名的指导原则:

  • 对所有对象全部使用大写,包括队列管理器,以防止在异构环境中出现可移植性问题。
  • 队列管理器名称在 MQ 网络中应该是唯一的,并反映队列管理器的位置、功能和环境(dev、test 等)。通道名称应该反映它们的功能和源/目标队列管理器连接流;对所有发送方和接收方通道使用 FROMQUEUEMANAGERNAME.TOQUEUEMANAGERNAME,对所有集群通道使用 TO.QUEUEMANAGERNAME。如果有多个通道连接到同一个管理器,可以在名称中使用不同的优先级或协议来扩展该约定,但是要保持在 20 个字符以内。另一个常见的最佳实践是使用 SOURCEQUEUEMANAGERNAME.TO.DESTQUEUEMANAGERNAME。
  • 将队列管理器名称保持简短,不要超过 8 个字符。
  • 队列的名称中不应该具有单词 QUEUE(因为它做出了暗示),也不应该在名称中具有拓扑(本地、远程、别名等等)。
  • 应用程序应该具有高级限定符,其中包含几个字符,后面跟着某个分隔符(例如句点),以便于对名称排序并明确队列的用途(例如 APPXYZ.SERVICE1.REQUEST)。
  • 不要在任何 MQ 对象的名称中使用空格,包括系统主机名称。
  • 对于 MQ 授权,尽管组名称和用户 ID 的最大长度是 20 个字符,还是要将名称保持在 12 个字符以下以防止复杂化。
  • 尽管允许使用特殊字符正斜杠 (/) 和百分号 (%),但是应该避免使用它们,因为它们会导致跨平台难题。

始终为队列管理器分配死信队列(dead letter queue,DLQ)

DLQ 是一个本地队列,也称为未送达消息队列。为每个队列管理器创建和分配一个死信队列,并使用它来捕获由于网络或目的地问题而未发送的消息,这是一个很好的实践。如果不定义 DLQ,应用程序中的错误可能导致通道关闭。如果发生这种情况,不仅队列将停止接收消息,而且可能影响 MQ 的正常操作——例如,可能不接收和执行管理命令。在必须保证确切地按顺序处理消息的严格应用程序环境中,可以省略 DLQ 以强制关闭消息的处理。建议为应用程序做好设计以避免这种场景。

此外,应该对 DLQ 进行监视,因为到达该队列的消息可能是错误。DLQ 应该已定义、可用,并为系统预期要处理的最大消息做好尺寸调整。在要求最可靠的环境中,将死信处理程序设置为触发器,以便自动重试死消息而无需人工介入。如果重试失败,则应该使用自定义的 DLQ 规则,根据需要转发或删除消息。MQ 提供了一个示例 DLQ 处理程序 (runmqdlq/amqsdlq),以供您学习和试验。

如果您还没有将某个 DLQ 与现有的队列管理器关联,可以使用 MQSC ALTER 命令将 DLQ 添加到队列管理器对象。

尽可能使用诸如 JMS 等标准

当今的动态业务需要正在驱使 IT 部门实现基于标准的计算。JMS 是基于 J2EE 的消息标准,并提供了一个标准 API,应用程序可以在执行企业消息时使用该 API 以实现应用程序可移植性。尽管 JMS 是与供应商无关的 Java 消息 API,但是不同 JMS 提供者的实现可能有所不同,了解不同实现之间的变化是非常重要的。在解决方案中使用诸如 JMS 等标准将促进应用程序可移植性,并减少对特定于供应商的 API 的依赖。这又会减轻集成挑战,并减少供应商绑定。SOAP/JMS 消息正日益成为支持 Web 服务的平台,从而将帮助客户完成基于 SOA 的实现。

在当今市场上,MQ 是 J2EE 应用程序的较为流行的 JMS 提供者之一。MQ JMS 实现无需桥接即可与其他 MQ 程序互操作。MQ JMS 实现同时支持点对点和发布/订阅消息模型。MQ V5.3 Fix Pack 8 或更高版本中为 MQ 提供了一个集成的代理。使用标准化的 JMS API,无需重新开发应用程序或接口即可升级到其他 JMS 代理,例如 WebSphere Message Broker。

在考虑性能的情况下进行构建

尽管 MQ 是为非常大的事务量而构建的,但是糟糕的体系结构和应用程序设计会危害其尽快和尽可能有效地处理消息的能力。为了缓解潜在的性能问题,下面提供了几个建议:

  • 消息大小和长度会影响处理消息的应用程序的性能以及网络数据传输时间。仅在消息中发送必需的数据。
  • 仅对关键或必需的数据使用持久消息。持久消息将记录到磁盘,并且会降低应用程序的性能。
  • 按消息或相关性标识符从队列中检索消息将降低应用程序的性能。这会导致队列管理器搜索队列中的所有消息,直到找到所需的消息为止。如果应用程序具有高性能要求,则应该将应用程序设计为按顺序处理消息。
  • MaxMsgLength 参数存储队列中允许的最大消息大小的值。可以更改 4 MB 的缺省值,以更好地适应应用程序的处理需要,这样将具有以最高效的方式使用系统资源的好处。
  • 确保将消息应用程序设计为彼此并行工作,并且应用程序的多个实例也并行工作。队列管理器在给定的时间仅执行某个队列中的一个服务请求,以维持完整性。避免在同步点中使用许多 MQPUT 调用而不提交这些调用的程序。受影响的队列会充满当前无法访问的消息,而其他应用程序或任务可能正在等待获取这些消息。
  • 当应用程序具有间隙性的消息传输需要时,可以使用 MQPUT1 调用以仅在队列上放置一个消息。对于其中放置多个消息的更大容量的应用程序,传统用法(使用 MQOPEN 调用,后面跟着一系列 MQPUT 调用和一个 MQCLOSE 调用)更为适当。
  • 如果您将要重用连接和队列,则应将它们保持打开,而不是重复地打开和关闭、连接和断开连接。
  • 应用程序能够在系统上运行的最大线程数量会影响解决方案的性能,在 Windows® 上尤其是如此。
  • 为通道配置断开连接间隔,以便通道上在一段时间后没有活动时,通道能转为非活动状态。这将降低开销并帮助改进总体性能。
  • MQ 性能常常受到磁盘 I/O 写入的限制。确保存储团队参与磁盘布局,以确保实现尽可能最快的可靠磁盘写入。

在程序中避免位置假设和固定队列名称

避免在应用程序中使用硬编码的 MQ 对象和位置名称,这样可以提供显著的体系结构灵活性、可移植性和部署灵活性。通过利用别名队列和/或模型队列以及 WebSphere 环境变量,部署灵活性将会得到增强。遵守这些规则,无需更改应用程序即可在不同的环境(不可靠的网络、混合操作系统、通信协议和混合语言环境)中部署应用程序。

在可行的情况下,对 MQ 服务器进行集群

如果您的基础结构能够支持的话,硬件和软件集群可以提供一种极好的方法来提高 MQ 解决方案的弹性、可伸缩性和性能。下面是在考虑 MQ 集群时的一些建议:

  • MQ 队列管理器在崩溃后不会自动重新启动,并且一般来讲,MQ 集群和诸如 HACMP 等基于硬件的集群在缺省情况下都没有提供这种行为。如果需要此功能,一般可以配置基于硬件的集群解决方案和系统自动化工具来提供这种行为。
  • 具有消息关联性的应用程序可能导致复杂化和非最优的集群负载管理例行程序。消除应用程序中的消息关联性可以增加应用程序可用性和可伸缩性选项。
  • 除非应用程序中有特定的消息关联性,否则不要在 MQOPEN 调用中使用 MQOO_BIND_ON_OPEN 选项将消息强制发送到特定的目的地。如果目标队列管理器不可用,则消息不会被路由到集群中的另一个队列管理器。
  • 不要对通道使用诸如 CONNAME 等通用名称。您需要指定完整存储库队列管理器的主机名称或 IP 地址。
  • 如果拥有适当的权限,您可以放置 (PUT) 其目的地为集群中任何队列的消息;但是您只能从集群队列的本地实例获取 (GET) 消息。
  • 您必须选择集群中的至少一个(最好是两个)队列管理器作为完整存储库。添加两个以上的完整存储库通常会导致总体性能下降,因为集群将需要发送附加的流量,并花费更多的时间维护所有存储库。
  • 在决定哪些服务器将承载完整存储库时,应选择高度可靠、管理良好并具有静态 IP 的服务器。
  • 使用中心与分支或总线模型以实现最大的灵活性和性能,在大型环境中尤其是如此。

设计具有队列管理器较少、每个队列管理器具有较多队列的基础结构

出于体系结构和性能的考虑,一般最好创建一个具有 100 个队列的队列管理器,而不是创建 100 个分别具有一个队列的队列管理器。在有意义的情况下,尽量限制 MQ 环境中的队列管理器数量。每个服务器上具有单个队列管理器一般可以满足该服务器上的所有队列和应用程序的需要。虽然队列管理器可以履行多种角色,但是职责分离应该在队列级别进行,最好是在队列名称中使用功能标识符来实现。

构建

捕获所有应用程序 MQ 调用中的完成和原因代码

适当设计您的应用程序以利用从 MQ 调用返回的完成和原因代码,这可以使应用程序能够确定消息是否安全到达并得到正确处理,或者消息的传送或处理是否存在问题。当您需要向 IBM Support 求助时,原因代码以及问题描述可以帮助加速问题的确定和解决。

编写 MQI 调用的开发代码时的技巧:

  • 每当 MQ 调用产生的完成或原因代码不为零,MQ 方法就会引发异常。
  • 在使用除 MQI 以外的其他 API 时,要确保捕获相联系的异常。在 JMS 的 MQ 实现的情况下,MQ 引发一个 Java MQException,其中包含完成代码、原因代码和异常详细信息。不要只是返回 JMSexception,因为其中不包含必需的完成和原因代码。

将应用程序代码编写为连续处理消息

在编写 MQ 应用程序时,考虑尽快从队列提取消息,并决定是立即处理它们还是将它们发送到故障队列。不要将应用程序代码设计为要求清除消息(例如不符合预期格式的消息)或需要管理员介入,然后应用程序才能处理队列中的附加消息。

正确地关闭或断开连接

适当编写应用程序代码,以便在断开连接或关闭之前正确地关闭和断开它们的连接。如果未能这样做,尤其是当客户端连接正在使用的时候,将导致连接挂起,从而增加资源消耗,并且可能延续至到达最大连接数的时候,从而阻塞新的连接。

注意不同 MQ 客户端的不同功能

并非所有的 MQ 客户端都提供相同的功能。在决定要使用哪个 MQ 客户端的时候,务必记住以下要点:

  • 了解连接选项,例如客户端绑定、服务器绑定、托管客户端绑定模式,以及客户端对 C、JMS、Java 或 .NET 应用程序的限制。例如,.Net MQ 客户端不支持 SSL 通道加密、XA 事务和通道压缩。另一个示例在于,Java MQ 客户端仅支持 TCP/IP 传输,并且在启动时不读取任何 MQ 环境变量。在此情况下,包括连接信息的所有环境变量存储在 qm.ini 文件中的 MQEnvironment 类中。
  • 网络和防火墙问题可能导致 MQ 连接失败,并且可能被误诊断为 MQ 问题。
  • 为连接的应用程序分配各自的唯一通道定义,以便管理员能够容易地确定是哪个应用程序在连接,以及实现附加的安全分段选项。
  • 在生产系统中,SYSTEM.DEF.SVRCONN 通道应该将一个非特权用户添加到 MCAUSER 字段,并且可能被置于停止状态。不应该配置应用程序使用此通道,而是应该为应用程序分配自己的不同通道。不利用系统对象不仅是个最佳实践,此通道还是一个已知的安全风险。
  • 当您设置 MCAUSER 属性的值时,应该将值包括在单引号中,以避免分布式平台上的区分大小写问题。

运行

使用安全最佳实践

在分布式系统上,mqm 组提供了对系统上所有 MQ 资源的管理访问权限。因此,要限制 mqm 组中的成员资格。

MQ 中的安全性可划分为两大类:MQ 使用者和 MQ 管理员。使用者通常以 ID 的形式存在,这些 ID 用于执行连接到 MQ 的应用程序。管理员是需要通过所包括的工具(例如 runmqsc)来交互式地查询或修改 MQ 配置的用户。在某些环境中,为简单起见,有时将应用程序帐户 ID(使用者)放在 mqm 组中。在这些情况下,应该锁定这些 ID,以防止将它们用于交互式登录,因为获得这些 ID 访问权限的任何用户都将拥有对 MQ 的完全管理控制。一种替代方法是使用 WMQ OAM setmqaut 工具,为每个资源或 MQ 对象(例如对列)指定 API 级别的详细权限。这项技术提供了更细粒度的控制,是可行情况下的首选方法。

关于管理权限,在需要考虑安全性和审核的情况下,应该使用诸如免费可用的 SupportPac MS0E 等第三方安全和配置工具来访问和修改 MQ 配置。在缺乏此类工具的情况下,只有 MQ 管理团队的成员才应该属于 mqm 组。应该为其他用户提供较低级别的权限,这些权限可通过 OAM 级别的 setmqaut 命令或通过使用诸如 MS0E 等 MQ SupportPacs 来授予。

在生产级别(受限制的访问)的计算机上使用 SYSTEM.ADMIN.SVRCONN 通道来限制远程管理权限。

在 MQ V5.3 或更低版本中,基于 Windows 的 MQ Explorer 管理工具使用 SYSTEM.ADMIN.SVRCONN 通道连接到队列管理器。不存在进一步保护该通道的工具,从而为要求限制访问权限的系统带来安全风险,因为了解队列管理器的任何人都可以在具有完全管理权限的情况下建立连接,并且在使用 Explorer 时没有任何审核跟踪。不过,此通道在缺省情况下是没有创建的,而是必须手动添加。在 MQ V6.0 或更高版本中,可以使用任何客户端通道进行管理访问,因此在生产系统上启用远程访问时,应考虑采用诸如 SSL 等附加措施。

不要将示例 get/put 实用工具用于生产目的

MQ 附带了演示如何获取和放置消息的示例程序。这些示例程序同时以已编译和未编译的形式提供。不要将这些程序一成不变地用作生产级应用程序以获取或放置消息,因为它们具有缓冲区限制,并且可能没有生产级应用程序所需要的可靠性或功能。

使用 runmqlsr 代替 inetd 侦听器

在 MQ V5.3 或更高版本中,runmqlsr 网络侦听器程序允许多线程连接。使用多线程进程而不是通过 amqcrsta 为每个连接发起新进程的优点是减少系统资源使用,以及消除潜在的管理中断。如果您有具有大量连接的系统(例如集成中心或 ESB),以及通过基于 UNIX 的 inetd 侦听服务(与 amqcrsta 程序相结合)来运行的现有侦听器,可以考虑将那些侦听器迁移到 runmqlsr。

将侦听器端口放在 qm.ini 文件的 TCP 节中(或 Windows 注册表中),以便那些端口与队列管理器很好地关联。然后,当侦听器启动时,将不需要引用任何命令行端口号。有关节的详细信息,请参阅 MQ 文档。

使用 SupportPacs 来扩展 MQ 功能

MQ 提供了许多称为 MQ SupportPacs 的免费可下载插件,以扩展功能。

  • MS03:savequeue 管理器——提供代码将所有 MQ 对象设置从 runmqsc 中导出,其导出格式允许以后被重用来导入(并重新创建)队列管理器配置。取决于您的环境,备份和恢复可能至关重要。
  • MS0E:runmqadm——提供一个管理包装,其中为不属于 mqm 组成员的用户提供了 runmqsc 和管理级别的访问权限,从而使您能够以更加细粒度的方式授予权限。
  • MA01:q 实用工具——允许您浏览消息并在队列之间移动它们。
  • MO03:qload 实用工具——允许您针对文件来回移动消息,以便传输到不同的系统或以后重用。
  • MS81:MQIPT——与 MQ 协同工作的附加产品,其采用 SSL 或 HTTP(S) 来通过防火墙建立连接隧道。可将其用于跨单个传输和端口聚集来自多个队列管理器的连接。
  • MC91:高可用性——提供用于在诸如 HACMP 和 Sun Cluster 等高度可用的 UNIX 系统上配置 MQ 的脚本和说明。

维护

在未使用第三方配置工具时,通过 MQSC 脚本来自动化所有的配置和更改。

养成以脚本的形式将任何队列管理器更改编写到 runmqsc 命令中的习惯。可以输入 runmqsc 编辑器中的任何命令还可以写到文件中以便以后执行。脚本可以在执行前使用 runmqsc -v < 文件名开关进行验证。在执行时,脚本的输出可容易地捕获到日志文件中以便以后审核。这个习惯将帮助避免代价高昂的输入错误,并在执行时加速更改的执行。

使用适当的日志记录机制

MQ 社区中的一个常见误解是以为线性日志记录更适合于生产级别的系统。除了循环日志记录优点以外,线性日志记录仅渐进地提供了对象恢复能力,并伴随着定期维护以防止文件系统装满的代价。如果将 MS03 SupportPac 设置为定期运行,则可以通过那些脚本重放对象的副本,从而最小化对线性日志记录的需要。循环日志记录队列管理器只需要较少的维护,并且由于磁盘空间用尽而导致的崩溃风险更低。

配置自动化的队列管理器维护

考虑创建脚本来自动化队列管理器的定期维护。维护应该包括定期的 savequeue 队列管理器 (MS03)、安全设置备份 (amqoamd)、线性日志清理(如适用的话),以及诸如 .ini 文件等其他重要设置的备份。此外,考虑审核 FDC 错误目录的内容,检查其中较旧并且应该删除、以及较新并且应该检查的 FDC 文件,因为它们指示了 MQ 系统中的关键错误。

许多第三方产品可以帮助提供此功能。在编写和维护您自己的脚本之前,应考虑这些供应商产品和免费可用的 SupportPacs,因为您自己的脚本在每个新的 MQ 版本推出时都需要进行维护。

定期计划安排和应用修复程序包

IBM Support 接到的许多求助电话都是由于已经在某个 IBM 修复程序包中解决的问题而发生的。因此,我们建议管理员定期计划、安排和应用 MQ 维护。

参考资料

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=WebSphere
ArticleID=341794
ArticleTitle=WebSphere MQ 最佳实践 Top 15
publish-date=10062008