MQ队列MQTT_DEPT尝试生成多个触发器消息

时间:2015-08-17 21:06:12

标签: jms ibm-mq

我们有一个HA应用程序,它运行在指向同一队列管理器的几个服务器上。因为消息排序很重要,所以我们使用信号量队列来确保没有两个应用程序正在从业务队列中读取消息,即使有多个消息等待在该队列上处理。

工作流程如下:

  1. 业务队列上设置了MQTT_DEPT触发器,以便在队列dept等于一时启动
  2. 业务队列接受一次或多次按摩。
  3. 当队列dept成为一个并将触发消息放入启动队列时,触发器将启动。
  4. 作为队列部门触发器,它应该在将触发器消息传递到启动队列后将其自身关闭
  5. 有一个MDB侦听该启动队列,它获取触发器消息
  6. 因为序列对我们来说至关重要,所以我们对启动队列设置了限制,使其最大队列为1。这样,一次只有一个MDB可以收到消息
  7. 当触发消息到达时,MDB会从业务队列中读取并读取所有消息,完成后会将触发器激活消息发送到专用队列。
  8. 一旦完成,它就会提交所有内容。触发器生成的消息将被丢弃。此时,触发器激活消息可用于处理。
  9. 激活MDB的触发器获取激活消息,然后在业务队列中重新启动队列部门触发器,以便整个过程可以重新启动。
  10. 在大多数情况下,一切正常。然而,偶尔我们会在死信队列中收到一些消息,这些消息会导致我们的监控工具进行支持调用。检查DLQ中的消息,我们注意到它们是触发生成的消息,并且发送到DLQ的原因是启动队列已满(请记住我们对最大一条消息的限制)。

    我们没有解释这是如何可行的。 IBM文档说在发送第一个触发器生成的消息之后关闭了触发,但是从我们正在试验的内容看起来好像第一个触发器生成的消息被处理,并且处于未提交状态,第二个触发器生成的消息被创建并发送到启动队列。无法交付(由于max dept = 1限制),它将其发送到死信队列。

    任何关于为什么会这样做以及如何绕过它的输入都将非常受欢迎。上午2:00的虚假支持电话肯定不好笑。

    提前感谢您的意见。

1 个答案:

答案 0 :(得分:0)

我们的问题的解释是关于IBM MQ触发文档,我们应该更仔细地阅读IBM note

注意:如果停止并重新启动队列管理器,则会重置TriggerInterval计时器。有一个小窗口,在此期间可以产生两个触发消息。当队列的trigger属性在消息到达且队列先前未为空(MQTT_FIRST)或具有TriggerDepth或更多消息(MQTT_DEPTH)的同时设置为启用时,该窗口存在。

一旦我们得到解释,解决方案就很简单了。不是将业务队列配置为将触发器生成的消息直接发送到启动队列,而是将其配置为发送到不同的队列,并在其上设置最大队列部门限制。然后我们实现了另一个MDB来获取这些触发器生成的消息并将它们重定向到启动队列。由于现有的队列部门限制,无法将触发器生成的消息传递到启动队列,因此该MDB实现了两次吞下任何异常。

换句话说,使用这个新的MDB,我们扮演的角色是从我们手中的MQ管理器提供触发器生成的消息,并使进程忽略由队列部门导致的任何传递失败。