使用 WebSphere Application Server V7(V8)的 WebSphere MQ 消息传递提供者激活规范处理消息

本文将介绍了 WebSphere Application Server 中的 WebSphere MQ 消息传递提供者激活规范,以及这些规范用于连接 WebSphere MQ 队列管理器和监控消息目标的机制,随后展示了应用程序服务器如何向消息驱动 bean 传递适当的消息以供处理。本文面向两类读者:需要调优系统的 WebSphere Application Server 管理员和开发人员;想了解应用程序服务器和 WebSphere MQ 之间的交互方式的 WebSphere MQ 管理员。

Paul Titheridge, WebSphere MQ Level 3 Support 团队服务专家, IBM

Paul Titheridge 的照片自从 2003 年起,Paul Titheridge 一直效力于英国 Hursley 的 IBM 实验室的 WebSphere MQ Level 3 Support 团队,他擅于解决 WebSphere MQ 和 WebSphere Application Server 之间交互的相关问题。



2011 年 12 月 27 日

免费下载:IBM® WebSphere® Application Server 试用版
下载更多的 IBM 软件试用版,并加入 IBM 软件下载与技术交流群组,参与在线交流。

免费下载:IBM® WebSphere® MQ V7.0.1 试用版
下载更多的 IBM 软件试用版,并加入 IBM 软件下载与技术交流群组,参与在线交流。

简介

IBM® WebSphere® Application Server V7 和 V8 提供基于 Java Message Service (JMS) 规范的异步消息传递。使用 WebSphere MQ 消息传递提供者,您可以编写一个消息驱动 bean,对 WebSphere MQ 目标(消息队列或主题)进行监听。当消息到达目标时,将会调用消息驱动 bean 中的 onMessage() 方法来处理消息。

在 WebSphere Application Server V7 和 V8 中,WebSphere MQ 消息传递提供者支持使用激活规范来监控 WebSphere MQ 队列管理器托管的目标。本文展示激活规范如何连接到分布式平台上的 WebSphere MQ,并描述监控查找消息的目标所使用的机制,以及如何在检测到适当的消息后调用消息驱动 bean。本文假定读者具有 JMS 和 WebSphere MQ 基本知识。

激活规范

简单说来,J2C 激活规范是一些受管理的对象,它们包含关于如何连接到 JMS 提供者的信息,以及 JMS 提供者上的受消息监控的目标的详细信息。当部署一个包含消息驱动 bean 的应用程序时,需要指定消息驱动 bean 要使用的激活规范。激活规范启动后,会连接到 JMS 提供者,打开 JMS 目标,然后监控它以查找消息。

图 1 和图 2 显示了使用 WebSphere Application Server Integrated Solutions Console 中的激活规范面板定义的样例 WebSphere MQ 激活规范。这个激活规范启动后,会创建一个 BINDINGS 模式连接,连接到名为 pault 的本地 WebSphere MQ 队列管理器,打开目标 jms/TestQueue,然后开始监控这个目标以查找消息。

图 1.
指定队列管理器名称和传输类型
图 2. 指定激活规范将监控的 JMS 目标
指定激活规范将监控的 JMS 目标

可以将激活规范配置为使用消息选择器,这样就可以只将符合选择标准的消息传递到消息驱动 bean。在图 2 中,没有指定消息选择器,因此所有到达目标的消息都会由这个激活规范处理。

激活规范找到一条适合的消息后,会在应用程序服务器中计划一个工作来处理消息。每条消息都需要一个 JMS 服务器会话才能运行,可以同时处理多条消息。

每个激活规范都有一个关联服务器会话池,会话池的大小控制一个激活规范可以同时处理的消息数量。服务器会话池的默认大小是 10,这表示一个激活规范最多可以同时处理 10 条消息。要更改服务器会话池大小,修改激活规范高级属性 Maximum server sessions,如图 3 所示:

图 3. 指定可以同时处理的消息数量
指定可以同时处理的消息数量

探测消息

激活规范用于探测 WebSphere MQ 队列管理器上托管的 JMS 目标的机制取决于正在使用的 WebSphere MQ 消息传递提供者模式。

WebSphere MQ 消息传递提供者普通模式

激活规范在以下情况下使用 WebSphere MQ 消息传递普通模式:连接到 WebSphere MQ V7 队列管理器且 Provider version 属性设置为 unspecified(默认值)或 7。在这种操作模式下,激活规范在连接到队列管理器并获取消息时利用 WebSphere MQ V7 的几个特性。激活规范在启动时:

  1. 会创建一个连接,连接到已设置为要使用的 WebSphere MQ 队列管理器。
  2. 如果激活规范配置为使用一个 Queue Destination,那么它会使用 WebSphere MQ API 调用 MQOPEN 以打开队列。
  3. 如果激活规范配置为使用一个 Topic Destination,那么它会发出一个 WebSphere MQ API MQSUB 调用以订阅相应的主题。
  4. 打开队列或订阅主题后,激活规范会使用 WebSphere MQ API 调用 MQCB 来注册一个回调。这个回调使用以下 WebSphere MQ GetMessageOptions 设置:
    • MQGMO_BROWSE_FIRST
    • MQGMO_UNMARKED_BROWSE_MSG
    • MQGMO_MARK_BROWSE_CO_OP
  5. 回调注册后,激活规范发出一个 WebSphere MQ MQCTL API 调用,告知队列管理器:激活规范已经准备好开始接收消息了。

现在,当适合的消息到达激活规范正在监控的队列或被发布到激活规范订阅的主题时,队列管理器标记该消息,阻止其他激活规范看到它,然后通过此前设置的回调将消息细节传递到激活规范。

WebSphere MQ 消息传递提供者迁移模式

激活规范连接到 WebSphere MQ 队列管理器的另一种方法是使用 WebSphere MQ 消息传递迁移模式。如果以下条件之一成立,则使用这种模式:

  • 激活规范被配置为连接到一个 WebSphere MQ V6 队列管理器。
  • 激活规范被配置为连接到一个 WebSphere MQ V7 队列管理器,且 Provider Version 属性设置为 6。
  • 激活规范已配置为连接到一个使用 CLIENT 传输的 WebSphere MQ V7 队列管理器,且正在使用 Sharing Conversations (SHARECNV) 属性设置为 0 的 WebSphere MQ 通道。

启动迁移模式时,激活规范:

  1. 创建一个连接,连接到已设置为要使用的 WebSphere MQ 队列管理器。
  2. 如果激活规范已配置为监控一个 Queue Destination,那么它会发出一个 MQOPEN API 调用,以打开队列。
  3. 如果激活规范已经配置为使用一个 Topic Destination,那么它:
    • 会打开一个主题订阅。
    • 会检查激活规范的Broker connection consumer subscription queueBroker durable subscriber connection consumer queue 这两个 Broker Properties 值,以查看 Broker 将为这个激活规范把消息发布到哪个 WebSphere MQ 队列。
    • 会调用 WebSphere MQ API MQOPEN,以打开相应的订阅队列。
  4. 在队列管理器上打开订阅队列后,激活规范会浏览队列,发出几个 MQGET API 调用,查找消息。激活规范结合使用 WebSphere MQ GetMessageOptions MQGMO_BROWSE_FIRST 和 MQGMO_BROWSE_NEXT,从头至尾扫描队列。

处理消息

激活规范探测到目标上的消息时(要么因为 WebSphere MQ V7 队列管理器已通过一个回调返回消息信息,要么因为激活规范已经浏览到一条适当的消息),那么它:

  1. 会构造一个消息引用来表示该消息。
  2. 会从激活规范服务器会话池获取一个服务器会话。
  3. 会通过消息引用加载服务器会话。
  4. 会使用应用程序服务器 Work Manager 计划一项工作。

然后,激活规范再返回去寻找更多消息。

获取服务器会话

如前所述,激活规范默认最多能同时处理 10 条消息。如果激活规范试图处理一条消息,但 10 个服务器会话全都在忙着处理消息,又会发生什么情况呢?在这种情况下,激活规范将被阻止,直到有一个服务器会话闲置。只要有一个服务器会话可用,激活规范就会马上使用消息引用加载它,然后计划一项新工作, 以便服务器会话可以再次运行。

计划工作

激活规范使用消息引用加载服务器会话后,就会安排一些工作,以便能够处理消息。这些工作都包含什么内容呢?Work Manager:

  1. 从 WebSphere Application Server WebSphere MQ 消息传递提供者 Resource Adapter 线程池中获取一个线程。这个线程池的名称为 WMQJCAResourceAdapter。
  2. 在这个线程池上运行这项工作。

工作计划好之后,应用程序服务器将在未来某个时点运行工作。这项工作在启动后:

  1. 会启动一个本地或全局 (XA) 事务,这取决于消息驱动的 bean 是否需要 XA 事务(在消息驱动 bean 的部署描述符中指定)。
  2. 如果是首次使用服务器会话,那么它:
    • 会创建一个到 WebSphere MQ 的新连接。
    • 会发出一个 MQOPEN API 调用,以打开消息驻留的队列。
  3. 会发出一个 MQGET API 调用,从 WebSphere MQ 获取消息。
  4. 会运行消息驱动 bean 中的 onMessage() 方法。
  5. onMessage() 运行完后,服务器会话会在退出之前完成本地或全局事务。

为提高性能,服务器会话用于与队列管理器的连接在处理完消息并完成工作后应保持开启状态。这样,下次使用服务器会话处理消息时,就不必重新连接到 WebSphere MQ 并重新打开包含消息的队列。在默认情况下,与激活规范关联的未使用服务器会话会在 30 分钟内保持开启状态,然后关闭。要延长这个超时时间,修改激活规范高级属性 Server session pool timeout 的值,如图 4 所示。

在轻型负载系统上,计划工作的时间和 Work Manager 启动工作的时间之间可能只间隔几毫秒。在繁忙的系统上,工作实际开始之前可能有较长的延迟时间。导致延迟的原因可能有两个:

  • WMQJCAResourceAdapter 线程池中没有闲置线程来运行工作。
  • Work Manager 能够从线程池中获取线程,但由于应用程序服务器太忙,不能启动工作。

Work Manager 记录计划工作和启动工作的时间,检查激活规范计划工作到启动工作之间的时间间隔。在默认情况下,激活规范预期工作在计划之后 10 秒内启动。如果 Work Manager 超出 10 秒后才启动工作,那么会返回一个 WorkRejected 异常到激活规范,发生与下面的应用程序服务器 SystemErr.log 中出现的类似异常:

Exception in thread "WMQJCAResourceAdapter : 1" java.lang.RuntimeException:
javax.resource.spi.work.WorkRejectedException: Work timed out (id=4), error code: 1
:   :   :   :   :   :   :   :   :   :   :   :   :   :   :   :   :   :   :   :   :   :  
Caused by: javax.resource.spi.work.WorkRejectedException: Work timed out
(id=4), error code: 1

当这样的异常发生时,队列管理器会将 Message Reference 中的消息标记为 "unmarked",以便能重新处理这些消息。可以使用 Start timeout 更改激活规范 Advanced 属性面板上的 10 秒的时间限制,如图 4 所示:

图 4. 修改服务器会话超时和等待工作开始的时间
图 4. 修改服务器会话超时和等待工作开始的时间

如前所述,如果 WMQJCAResourceAdapter 线程池中没有足够的线程,工作可能会被延迟,这引发了一个明显的问题 “这个线程池的大小应该是多少?”。激活规范对每个应用程序服务器使用一个线程池来运行服务器会话。每个激活规范都有一个名为 Maximum server sessions 的高级属性,可用于定义并发服务器会话的最大数量。由于每个服务器会话都用于处理消息,因此这个属性本质上表明使用这个激活规范的消息驱动 bean 可以同时处理多少消息。因此,为了确定 WMQJCAResourceAdapter 线程池的大小应该是多少,需要对应用程序服务器上每个 WebSphere MQ 消息传递提供者激活规范的 Maximum server sessions 属性值进行合计。例如,假设您定义了 25 个激活规范,每个激活规范的 Maximum server sessions 属性值都设置为 3。这样,最多可以同时运行 75 个服务器会话,每个会话都使用 WMQJCAResourceAdapter 线程池中的一个线程。图 5 显示了 WebSphere Integrated Solutions Console 中的 WMQJCAResourceAdapter 线程池,您可以在其中更改这个线程池的大小:

图 5. 更改应用程序服务器中定义的所有激活规范可用的最大线程数量
图 5. 更改应用程序服务器中定义的所有激活规范可用的最大线程数量

如果您看到应用程序服务器 SystemOut.log 文件中开始出现 WorkRejected 错误,那么首先应该检查 WMQJCAResourceAdapter 线程池的大小是否足够处理您的激活规范所需的所有服务器会话。如果线程池大小适当,那么导致错误的原因是 Work Manager 不能在指定的时间内启动工作请求。这时,您应该增加激活规范高级属性 Start Timeout 的值,或者减少您的应用程序服务器系统上的负载。

使用 WebSphere MQ 消息传递提供者普通模式

如上所述,探测到消息和消息驱动 bean 处理消息之间可能会出现延迟的情况有三种:

  • 与激活规范关联的所有服务器会话都正在使用中。
  • WMQJCAResourceAdapter 线程池中的所有线程都用于处理消息。
  • 计划工作和 Work Manager 实际启动工作之间存在延迟。

如果激活规范正以 WebSphere MQ 消息传递提供者普通模式运行,则队列管理器在将消息细节返回激活规范之前标记消息。标记消息意味着其他激活规范(或 WebSphere Application Server Listener Port),无论是否在同一个应用程序服务器上运行,都看不到此消息,这样可阻止另一个消息驱动 bean 在服务器会话能够处理消息之前获取消息。

在默认情况下,消息被标记 5 秒钟。要更改这个时间,修改 WebSphere MQ 队列管理器属性 Message mark browse interval (MARKINT)。

WebSphere MQ 将要处理的消息细节传递到激活规范后,5 秒计时器开始。在这 5 秒期间内:

  1. 激活规范必须从服务器会话池中获取一个服务器会话。
  2. 服务器会话必须加载要处理的消息的细节。
  3. 必须被计划工作。
  4. Work Manager 必须启动工作请求。

如果获取服务器会话或从 WMQJCAResourceAdapter 线程池获取线程过程中出现延迟,或者系统繁忙,并且 Work Manager 计划工作耗费了很长时间,那么 WebSphere MQ 传递消息细节和激活规范实际使用消息细节之间的时间可能会超过 5 秒钟。如果遇到这种情况,又会发生什么事呢?

如果消息在队列上等待 5 秒以上,那么队列管理器将取消它的标记,另一个激活规范或监听器端口就会随时获取该消息。如果发生这种情况,那么当此前收到这条消息的细节的服务器会话试图获取消息时,就会发现此消息已不再位于目标上,于是,它会将以下消息写入应用程序服务器 SystemOut.log 中:

CWSJY0003W: JMSCC0108: WebSphere classes for JMS attempted to get 
a message for delivery to an message listener that had previously been 
marked using browse-with-mark, but the message was not there.

如果看到这条消息,您有三个选择:

  • 增加 WebSphere MQ 队列管理器属性 Message mark browse interval (MARKINT) 的值,向激活规范提供更多时间以获取消息。如果您有多个应用程序正在监控同一个目标,且希望快速对消息进行处理,那么您应该仔细考虑是否采用这种方法,因为增加消息标记时间将阻止其他应用程序获取消息。
  • 调优应用程序服务器,以免它阻止等待服务器会话或等待来自 WMQJCAResourceAdapter 线程池的线程。为此,同时增加服务器会话池和线程池的大小。此项更改意味着消息可以在默认的消息浏览标记间隔内处理,但由于应用程序服务器能够同时处理更多消息,因此会耗用更多资源。
  • 什么也不做。不建议这样做,因为这意味着激活规范将浪费时间和资源,试图获取另一个应用程序已经获取并处理的消息。

结束语

本文描述了激活规范从 WebSphere 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=783075
ArticleTitle=使用 WebSphere Application Server V7(V8)的 WebSphere MQ 消息传递提供者激活规范处理消息
publish-date=12272011