通过Omegamon XE和Tivoli Monitoring改进WebSphere MQ 集群工作负载平衡

Ian Vanstone, 顾问软件工程师, IBM

简介: 本文展示如何使用 WebSphere MQ Clustering、Omegamon XE for Messaging 和 Tivoli Monitoring,通过降低由应用程序停用导致的失败和服务超时,来改进消息传递系统中的服务可用性。

简介

IBM® WebSphere® Clustering 提供了一组强大的消息工作负载平衡特性。默认情况下,消息是基于队列管理器可用性实现负载平衡的,而不是基于消息使用方应用程序的可用性。因此,可以将消息发送到消息使用方应用程序不积极提供服务的集群队列。WebSphere MQ 触发机制可用于避免消息在队列上保持未处理状态,但有时该机制并不适用,例如当应用程序拥有特殊的连接池或启动逻辑时。如果未启用触发机制且消息在队列上保持未处理状态,那么服务失败或超时的风险将增加。

本文展示如何只将消息发送到正由消息使用方应用程序积极提供服务的那些队列。这个解决方案降低了由不适合使用触发机制的 WebSphere MQ 应用程序导致的失败和服务超时。这个解决方案使用:

  • WebSphere MQ Clustering 来平衡消息工作负载;
  • Omegamon XE for Messaging 和 IBM Tivoli Monitoring 来监控 WebSphere MQ 队列的状态并自动化配置更改。

为何基于应用程序可用性实现工作负载平衡?

WebSphere MQ Clustering 并不基于消息使用方应用程序的可用性来实现消息负载平衡,比如通过一个含三个队列管理器的集群来实现(见图 1)。连接到 QM1 的消息生成方应用程序将消息放置到队列 CLUSQ1。默认情况下,集群机制在 QM2 和 QM3 上的 CLUSQ1 的各个实例之间均等地平衡消息负载,即使一个消息使用方应用程序当时不对 QM3 上的 CLUSQ1 提供服务。


图 1. 一个 WebSphere MQ 集群示例
一个 WebSphere MQ 集群示例

在多数环境中,如果消息到达 QM3 上的 CLUSQ1,WebSphere MQ 触发机制可用于启动一个消息使用方应用程序。在这个示例中,消息使用方应用程序在一个由于计划外停用而离线的应用程序服务器中运行。由于特殊的启动流程,触发机制不能用于启动该应用程序服务器。在这种情况下,当该应用程序服务器离线时,最好将所有消息发送到拥有一个活动应用程序服务器和消息使用方应用程序的 QM2 上的 CLUSQ1 中。通过活动消息使用方应用程序发送消息到队列的需求与以下几种情景相关:

  • 一个服务级别协议(SLA)指定最大消息处理时间;
  • 一个服务超时已在一个或多个服务组件中配置;
  • 某人发起这个服务且必须等待一个答复,并且最终将放弃等待。

您可以基于应用程序可用性来构建工作负载平衡机制,这里要用到 WebSphere MQ 的一些特性和其他一些产品 —— 本例中是 IBM Tivoli Monitoring 和 Omegamon XE for Messaging。

使用的产品

本小节介绍如何使用这三个产品来基于应用程序可用性实现消息负载平衡。要参考关于其他解决方案的讨论,请参见下面的 备用方案 小节。

WebSphere MQ Clustering

WebSphere MQ 集群机制用于将多个队列管理器合并为一些小组。如这个解决方案所示,集群机制有两个主要目的:

  1. 集群机制提供一个消息工作负载平衡系统,通常用于在多个队列管理器之间分布消息传递工作负载,或者将消息发送到可用性最高的队列管理器。本文中的解决方案增强了这些工作负载平衡特性。
  2. 集群机制提供一个对象自动定义系统,支持创建在拓扑变更期间保持灵活性的 WebSphere MQ 消息传递网络。其结果是一个更简单的管理模型。例如,在集群中添加或删除队列管理器比在通过常规(非集群)通道互联的大型 WebSphere MQ 网络中完成相同的操作更简单。集群机制在 SOA 消息传递范式中使用得越来越多,SOA 消息传递范式要求多个队列管理器直接互联,以提供一个灵活的企业服务总线(ESB)。这个解决方案使用集群自动定义特性,以在多个集群队列管理器之间自动共享对象定义更改。

Omegamon XE for Messaging

Omegamon XE for Messaging 为 WebSphere MQ 和 WebSphere Message Broker 提供监控和配置特性。在这个解决方案中,它用于监控 WebSphere MQ 队列的状态。

IBM Tivoli Monitoring

Tivoli Monitoring 提供一些基础设施和工具来监控、配置和自动化一些健康业务系统的运行。其他许多监控产品都可以连接到 Tivoli Monitoring,提供一个集中的企业级监控解决方案。这个解决方案联合使用 Omegamon XE for Messaging 和 Tivoli Monitoring 来监控、配置和自动化对 WebSphere MQ 资产的更改。Tivoli Enterprise Portal 图形用户界面用于配置 Omegamon XE for Messaging 的特性并自动化操作。Tivoli Monitoring 向 Tivoli Enterprise Portal 提供替代管理界面。

解决方案架构

这个解决方案包括三个阶段,以基于应用程序可用性实现工作负载平衡。

检测应用程序的健康状况

开放输入计数队列属性(IPPROCS)用于表明消息使用方应用程序的存在。IPPROCS 显示允许处理队列消息的应用程序量。一个非零开放输入计数表明至少有一个应用程序准备好处理队列上的消息。开放输入计数为零表示没有一个应用程序准备好处理队列上的消息。

影响集群工作负载平衡算法

放置队列属性(PUT)用于影响集群工作负载平衡。在这个解决方案中 PUT 的功效在于它基于集群机制的两个强大特性。第一,集群工作负载算法不会将消息发送到禁用放置的队列。第二,集群机制在集群队列对象定义的 put 属性改变时自动传播这些定义。以上面的图 1 为例,如果 QM2 上的 CLUSQ1 更改为禁用放置,则对象变更被自动传播到 QM1。因此,由连接到 QM1 的应用程序放置的消息将不会被发送到 QM2,这样,所有消息都将被发送到 QM3。如果 QM2 上的 CLUSQ1 稍后更改为允许放置,同样,对象更改将自动传播到 QM1,从而使消息工作负载在 QM2 和 QM3 之间均衡分布。

确保消息得到及时处理

如果消息排列在缺乏活动消息使用方应用程序的集群队列上,最好重新分发消息,以便将它们发送到拥有活动消息使用方应用程序的队列。这个解决方案使用一个简单的应用程序从没有活动消息使用方应用程序的集群队列提取消息,并将它们放置到另一个集群队列中。集群工作负载平衡算法不允许将消息放置到禁用放置的队列(没有活动消息使用方应用程序的队列)。通过这种方法,消息被重新分发到在其中得到及时处理的可能性最大的队列中。

解决方案组件

关键的解决方案组件列示如下并如图 2 所示:

  • 三个 WebSphere MQ 集群队列管理器:
    • QM1 连接了一个消息生成方应用程序,并将消息放置到集群队列 DCQ1 中。
    • QM2 和 QM3 分别托管集群队列 DCQ1 的一个实例。这个解决方案确保消息只被发送到拥有活动消息使用方应用程序的那些实例。
    • QM2 和 QM3 通过 Omegamon XE for Messaging 代理监控。
  • 两个 shell 脚本:
    • 放置启用脚本,用于对队列启用放置。
    • 放置禁用脚本,用于对队列禁用放置。此脚本还执行 Q 应用程序(WebSphere MQ SupportPac MA01 提供)来重新分发消息。这个 Q 应用程序简单易用,且有利于测试。
  • Tivoli Monitoring 组件被连接到 Omegamon XE for Messaging 代理,并使用在一台笔记本电脑上运行的 Web 浏览器上的 Tivoli Enterprise Portal 查看。Tivoli Enterprise Portal 用于配置一些监控队列的开放输入计数并自动执行这些 shell 脚本的情景,比如:
    • 如果开放输入计数为零,则执行放置禁用脚本。
    • 如果开放输入计数不为零,则执行放置启用脚本。


    图 2. 解决方案架构
    解决方案架构

配置解决方案

本文介绍的一般原则可以根据产品和平台组合的不同而相应进行调整。这个特殊的解决方案使用以下 AIX V5.3 软件部署和测试:

  • Tivoli Monitoring V6.2.1
  • Omegamon XE for Messaging V6.0.1.1
  • WebSphere MQ V6.0.2.5

这些配置说明做出以下假设:

  • Omegamon XE for Messaging 和 Tivoli Monitoring 是预先配置的,以便在 Tivoli Enterprise Portal 中监控队列管理器。
  • 三个队列管理器(QM1、QM2 和 QM3)连接到一个 WebSphere MQ 集群中。
  • 集群队列 DCQ1 同时定义在 QM2 和 QM3 上,其 DEFBIND 队列属性设置为 NOTFIXED。例如:DEF QL(DCQ1) CLUSTER(C1) DEFBIND(NOTFIXED)

设置 shell 脚本

  1. 将以下 shell 脚本存储在目录 /opt/MQScripts 中的 Machine2 和 Machine3 上。
    • queueEnable.sh 对队列启用放置。
      #!/bin/sh
      #
      
      # Check that the required parameters were used
      if [ $# -ne 2 ]
      then
         echo "$0 : You must supply the queue and qmgr"
         exit 1
      fi
      
      # Put-enable the queue
      echo 'ALTER QL(' $1 ') PUT(ENABLED)' | runmqsc $2
      	

    • queueDisable.sh 对队列禁用放置并重新分发队列上的消息。
      #!/bin/sh
      #
      
      # Check that the required parameters were used
      if [ $# -ne 2 ]
      then
        echo "$0 : You must supply the queue and qmgr"
        exit 1
      fi
      
      # Put-disable the queue 
      echo 'ALTER QL(' $1' ) PUT(DISABLED)' | runmqsc $2 
      
      # Redistribute any messages on the queue by 
      # using the Q application
      /opt/IBM/MA01/q -I$1 -m$2 -o$1 –p1
      	

      这个解决方案使用一些 shell 脚本,以便在一个地方、以一致的方式配置 WebSphere MQ 并执行消息重新分发应用程序。或者,您也可以使用 Tivoli Enterprise Portal 工作流和 Omegamon XE for Messaging 执行上述操作。

  2. 下载 WebSphere MQ SupportPac MA01 到 Machine2 和 Machine3 上,将 Q 应用程序存储在 /opt/IBM/MA01 目录中。

设置 Tivoli Enterprise Portal 情景

  1. 启动一个 Web 浏览器,登录到 Tivoli Enterprise Portal。
  2. 单击工具栏上的 Situations Editor 图标(Situations Editor 图标):

    图 3
    工具栏

  3. 展开 Situation Editor 窗口中的 MQSERIES 区域:

    图 4
    图 4

  4. 右键单击 MQSERIES 并选择 Create New,开始创建与不含消息处理应用程序的集群队列关联的情景。
  5. 输入新情景的名称、说明和类型:

    图 5
    Create New 窗口

  6. 在 Select Condition 窗口中,选择 Queue Data 属性组,然后选择 Input OpensQueue Name 属性项目。然后单击 OK

    图 6
    Select Condition 窗口

  7. 选择 Situation Editor 窗口中的 Formula 选项卡。设置公式,以便在没有应用程序拥有对输入开放的 DCQ1 队列时触发该情景:
    1. 设置 Queue Name 值为:== 'DCQ1'
    2. 设置 Input Opens 值为:== 0
    3. 设置 Sampling interval 为:5 分钟

    根据最大消息处理时间来设置采样间隔。



    图 7
    Situation Editor 窗口 -- Formula 选项卡

  8. 选择 Situation Editor 窗口中的 Distribution 选项卡。将适当的队列管理器添加到指定列表。在这个示例中,DCQ1 队列位于 QM2QM3 队列管理器上。
  9. 选择 Situation Editor 窗口中的 Action 选项卡:
    1. 设置 System Command 值为:
      /opt/MQScripts/queueDisable.sh
      &{Queue_Data.Queue_Name}
      &{Queue_Data.MQ_Manager_Name}
      	

    2. 选择 Take action on each item 单选按钮,以便为满足公式要求的每个队列触发该情景。
    3. 选择 Execute the Action at the Managed System (Agent) 单选按钮,以便系统命令在正确的机器(托管脚本的机器)上执行。
    4. 选择 Don't take action twice in a row(一直等待,直到情景变为假然后再次为真)单选按钮,以便脚本只在应用程序状态变化时执行。


    图 8
    Situation Editor 窗口 -- Action 选项卡

  10. 单击 Apply 保存情景。
  11. 展开 Situation Editor 窗口中的 MQSERIES 区域。

    图 9
    Situation Editor 窗口 -- MQSERIES 区域

  12. 右键单击 MQSERIES 并选择 Create New,开始创建与含消息处理应用程序的集群队列关联的情景。
  13. 输入新情景姓名、说明和类型:

    图 10
    Create New 窗口

  14. 在 Select condition 窗口中,选择 Queue Data 属性组,然后选择 Input OpensQueue Name 属性项目。然后单击 OK

    图 11
    Select condition 窗口

  15. 选择 Situation Editor 中的 Formula 选项卡。设置公式,以便在任意应用程序拥有对输入开放的 DCQ1 队列时触发该情景:
    1. 设置 Queue Name 值为:== ‘DCQ1’
    2. 设置 Input Opens 值为:> 0
    3. 设置 Sampling interval 值为:5 分钟

    根据最大消息处理时间来设置采样间隔:



    图 12
    Situation Editor 窗口 -- Formula 选项卡

  16. 选择 Situations Editor 窗口中的 Distribution 选项卡。将适当的队列管理器添加到指定列表。在这个示例中,DCQ1 队列位于 QM2QM3 队列管理器上。
  17. 选择 Situations Editor 窗口中的 Action 选项卡。
    1. 设置 System Command 值为:
      /opt/MQScripts/queueEnable.sh
      &{Queue_Data.Queue_Name}
      &{Queue_Data.MQ_Manager_Name}
      	

    2. 选择 Take action on each item 单选按钮,以便为满足公式要求的每个队列触发该情景。
    3. 设置 Execute the action at the Managed System (Agent) 单选按钮,以便系统命令在正确的机器(队列管理器托管脚本的本地机器)上执行。
    4. 设置 Don't take action twice in a row(一直等待,直到情景变为假然后再次为真)单选按钮,以便脚本只在应用程序状态变化时执行。


    图 13
    Situation Editor 窗口 -- Action 选项卡

  18. 单击 Apply 保存情景。
  19. 右键单击 MQQueueEnable 情景并单击 Start Situation
  20. 右键单击 MQQueueDisable 情景并单击 Start Situation
  21. 单击 OK 退出 Situation Editor。

配置现在完成,准备好进行测试。

测试解决方案

测试摘要:

  1. 将消息使用方应用程序连接到每个集群队列 DCQ1 并检查这两个队列是否都启用了放置。
  2. 使用一个连接到 QM1 的消息生成方应用程序将消息放置到 DCQ1。
  3. 停止其中一个消息使用方应用程序,并使用消息生成方应用程序将更多消息放置到 DCQ1 队列中。这样,消息排列在没有活动消息使用方应用程序的 DCQ1 的实例上。
  4. 检查一旦情景触发后,没有消息使用方应用程序的 DCQ1 的实例是否将禁用放置,它的消息是否将被重新分发到带有一个活动消息使用方应用程序的 DCQ1 的实例上。

这个测试应用程序就是来自 WebSphere MQ SupportPac MA01 的 Q 应用程序。要测试这个解决方案,请执行以下步骤:

  1. 下载 WebSphere MQ SupportPac MA01 到 Machine1,将 Q 应用程序存储在 /opt/IBM/MA01 目录中。
  2. 启动消息使用方应用程序,以便它们可以从 DCQ1 的实例获取消息:
    1. 在 Machine2 上运行以下命令:/opt/IBM/MA01/ q -IDCQ1 –mQM2 -w10000
    2. 在 Machine3 上运行以下命令:/opt/IBM/MA01/ q -IDCQ1 –mQM3 -w10000
  3. 在 QM1 上启动一个消息生成方应用程序以将消息放置到 DCQ1:
    1. 在 Machine1 上运行以下命令:/opt/IBM/MA01/ q -oDCQ1 -mQM1
  4. 在 Tivoli Enterprise Portal 中等待情景的采样间隔中指定的时长,然后检查 QM1 上的集群队列的放置属性。在 Machine1 上运行以下命令并检查 DCQ1 的两个实例的 PUT 属性是否设置为 ENABLED:echo 'DIS QC(DCQ1) ALL' | runmqsc QM1
  5. 使用连接到 QM1 的消息生成方应用程序将 100 条消息放置到队列 DCQ1。在 Machine1 上的 Q 应用程序会话中运行以下命令:#100
  6. 确保消息到达 QM2 和 QM3 上。确保文本(比如,(4 bytes) #100)同时出现在 Machine2 和 Machine3 上的 Q 应用程序会话中。
  7. 按下 Ctrl + C 组合键终止 Machine2 上的消息使用方应用程序:
    1. 使用连接到 QM1 的消息生成方应用程序将另外 100 条消息放置到队列 DCQ1。在 Machine1 上的 Q 应用程序会话中运行以下命令:#100
    2. 立即检查,看看消息现在是否在 QM2 上的 DCQ1 中排队。在 Machine2 上运行以下命令并确保 DCQ1 队列拥有大于零的 CURDEPTH: echo 'DIS QL(DCQ1) CURDEPTH' | runmqsc QM2
  8. 在 Tivoli Enterprise Portal 中等待情景的采样间隔中指定的时长(例如,5 分钟),然后检查 QM1 上的集群队列的放置属性。在 Machine1 上运行以下命令并检查 QM2 队列的 PUT 属性是否设置为 DISABLED,QM3 队列的 PUT 属性是否设置为 ENABLED: echo 'DIS QC(DCQ1) ALL' | runmqsc QM1
  9. 还要检查 QM2 上的消息是否已经被重新分发。在 Machine2 上运行以下命令并检查 DCQ1 队列的 CURDEPTH 是否等于零: echo 'DIS QL(DCQ1) CURDEPTH'| runmqsc QM2

测试到此完毕。

备用方案

这个解决方案包括三个阶段,以基于应用程序可用性实现工作负载平衡:

  1. 检测应用程序的健康状况
  2. 影响集群工作负载平衡算法
  3. 确保消息得到及时处理

本小节介绍如何使用备用方案实现每个阶段。

检测应用程序的健康状况

可以使用开放输入计数来大致估计哪些队列拥有准备好处理消息的应用程序,但这种方法并不总是可靠。如果一个队列拥有一个非零开放输入计数,一个应用程序可能没有准备好处理消息。可能的原因包括:

  • 应用程序拥有开放的队列,但是并不健康或者没有准备好处理消息(例如,它已经耗尽工作线程)。
  • 应用程序没有能力处理相关服务级别协议中定义的消息速率。
  • 机器本身不健康(例如,CPU 利用率已经为 100%)。
  • 错误的应用程序连接到队列。

使用开放输入计数的备用方案:

  • 使用队列的当前深度。如果队列深度比较高,则假定应用程序不健康或不能够处理消息的速率。队列深度事件能够用于发起配置更改。
  • 监控实际的应用程序进程。如果进程正在运行,则假定应用程序是健康的。
  • 添加一个应用程序接口,以便它能够被轮询。如果对该接口的调用返回一个良好的返回码,则假定应用程序是健康的。
  • 这些备用方案可以联合使用,它们可以通过使用 Omegamon XE for Messaging 和 Tivoli Monitoring 的特性被全部或部分实现。

影响集群工作负载平衡算法

对队列启用和禁用放置是一种好方法,因为集群机制会自动把更改传播到放置属性并在平衡工作负载时使用该属性。集群工作负载等级(CLWLRANK)是适合这个自动更改传播模型的另一个队列属性。集群工作负载等级属性与放置属性存在以下两方面区别:

  • 它的粒度更细。集群工作负载等级的值范围从 0 到 9,而不包含启用和禁用这两个值。消息被发送到级别最高的一个或多个队列,因此这个细粒度允许对队列排序,以表明应用程序可用性的等级。
  • 它不会导致消息放置在所有队列都拥有同等低值的情况下失败。如果一条消息被放置到一个所有队列实例都禁用放置的队列中,则放置失败,放置应用程序收到一个坏返回码(MQRC_CLUSTER_PUT_INHIBITED)。如果一条消息被放置到一个所有队列实例都被同等评级的队列中,则对该队列的放置将成功完成,且消息工作负载在所有队列实例之间均衡分布。

如果您使用集群工作负载等级属性,则应将集群工作负载使用队列(CLWLUSEQ)设置为 ANY,以便消息工作负载被平衡到远程队列,即使存在一个本地工作队列。

放置属性和集群工作负载等级属性在行为上的区别提供了两类服务:

  • 如果您希望(队列实例不含活动应用程序的队列)放置失败,则可以使用放置属性。
  • 如果您希望(队列实例不含活动应用程序的队列)放置完成且消息被排队,则可以使用集群工作负载等级属性。

还有其他备用方案,包括影响集群工作负载算法的集群通道属性(例如,集群工作负载等级或集群工作负载权重)。

确保消息得到及时处理

在本文介绍的解决方案中,Q 应用程序用于将消息重新分发到拥有活动应用程序的队列。您必须确保消息被正确地重新分发。在一个集群队列的所有实例都禁用放置的情况下,重新分发应用程序将失败(由于 MQRC_CLUSTER_PUT_INHIBITED),导致消息被回滚到队列的原始本地实例上并在那里等待,直到启动一个本地应用程序来处理消息。如果一个消息使用者稍后在一个远程队列管理器上启动,重新分发流程不会重新启动,因此消息将保持排队状态,即使集群中的其他地方有一个健康的消息使用方应用程序可用。可以重新编写应用程序,以便在重新分发消息之前将所有队列实例的状态纳入考虑范围,并在重新分发成功完成之前按照计划的间隔运行。

如果使用集群工作负载等级属性,要确保将消息重新分发到同等低级的队列不会导致从队列管理器到队列管理器的消息循环,这是重新分发循环的一部分。

消息处理时间由服务级别协议规定。在为 Tivoli Enterprise Portal 中定义的情景设置采样间隔时,应该考虑这些时间。WebSphere MQ 触发机制通常是基于监控和采样启动应用程序的推荐备用方案,尽管如前所述,该特性并不适合所有环境。

尽管集群自动定义和对象更改传播功能非常有用,但您需要确保队列管理器之间的通道(特别是来往于完整存储库队列管理器的通道)保持健康。如果通道不健康,集群对象更改消息则不能流动,导致工作负载平衡方法选择基于过时数据(比如,队列的放置属性)。您可以使用 Omegamon XE for Messaging 和 Tivoli Monitoring 这样的产品来监控通道状况并就通道问题向操作人员发出警报,从而避免这种情况发生。

结束语

本文展示如何使用 WebSphere MQ Clustering、Omegamon XE for Messaging 和 Tivoli Monitoring,通过降低由应用程序停用导致的失败和服务超时,来改进消息传递系统中的服务可用性。这些产品提供可靠的工具来管理和监控您的消息传递基础设施,从而改善可用性。这些产品还链接到范围广泛的其他 Tivoli 产品,支持一种集中、整体的消息传递系统监控方法。

原文链接:http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1005_vanstone/1005_vanstone.html

请使用浏览器的分享功能分享到微信等