使用MQ JMS类和spring重新传递MQ消息



我们的应用程序正在使用带有spring的MQ JMS类来消费来自WebSphere MQ的消息。MQ队列定义未为退避阈值(BOTHRESH)和退避队列名称(BOQNAME)设置任何值。在会话事务处理模式中,当处理消息时发生异常时,不会发生消息传递重试。我看到一个异常,说并没有定义阻塞队列。由于未定义,它正试图将消息添加到死信队列中。这也失败了。我的问题是-

  1. 当BOTHRESH=0时,MQ JMS类是否可以重新传递消息
  2. 使用以上设置,是否可以使用重新传递计数通过应用程序代码管理消息传递重试

根据IBM知识中心关于退出行为的页面,

如果回退阈值为零,则有害消息处理为禁用,并且毒消息保留在输入队列中。否则当回退计数达到阈值时,消息为发送到命名的退出队列。如果回退计数达到阈值,但消息无法进入退出队列消息被发送到死信队列或被丢弃。

其目的是,实际上,您可以使用JMSX_DELIVERY_COUNTJMS_IBM_MQMD_BackoutCount来管理应用程序代码中的重新交付。

我怀疑知识中心至少有点错误,因为它说重新排队失败的消息将被丢弃。我认为这只适用于非持久性消息,并且已经提交了要求澄清的反馈。

然而,我对回退行为的理解是,它在知识中心中得到了正确的描述,并且您看到的行为不是IBM JMS类所期望的。有两种可能性。首先,意外行为是在Spring代码中实现的,而不是IBM的JMS代码。第二个原因是MQ JMS有一个错误,并且没有按照文档进行操作。

通常我会应用"什么更有可能?"测试,而"MQ bug"不会上升到该列表的顶部。然而,我不知道Spring,也不知道专门的毒消息处理代码的可能性,或者Spring代码的总体质量。因此,我建议使用独立的JMS代码来执行相同的测试,或者打开PMR并与IBM支持部门合作来跟踪代码并隔离回退失败的类。

我使用的MQ 7.5带有BackOut BOTHRESH(1)和BOQNAME(SAMEQUEUE)。在我的例子中,我使用的SOURCE QUEUE与BOQNAME中的相同,所以我的主QUEUE也是我的DLQ QUEUE,它允许消息旋转到我的消费者。在Spring配置中,我只使用sessionTransacted="true"。我做的另一件事是在BOQNAME中使用DLQ时,过了一段时间后,我使用"q"实用程序再次将消息从DLQ移动到主队列。

希望能有所帮助。

最新更新