MQ 队列 MQTT_DEPT 试图生成多个触发消息
MQ Queue MQTT_DEPT trying to generate multiple trigger messages
我们有一个 HA 应用程序,它在指向同一个队列管理器的几台服务器上运行。因为消息排序很重要,所以我们使用信号量队列来确保不会有两个应用程序从业务队列中读取消息,即使该队列上有多个消息等待处理也是如此。
工作流程如下:
- 业务队列设置了一个MQTT_DEPT触发器,当队列部门等于一个
时触发
- 业务队列接收一个或多个消息。
- 当队列部门变成一个并将触发器消息放入启动队列时触发器启动。
- 作为队列部门触发器,它应该在将触发器消息传递到启动队列后自行关闭
- 有一个 MDB 正在侦听获取触发消息的启动队列
- 因为顺序对我们来说至关重要,所以我们对启动队列进行了限制,使其最大队列部门为 1。这样一次只有一个 MDB 可以获取消息
- 当触发器消息到达时,MDB 会去读取业务队列中的所有消息,完成后它会将触发器激活消息发送到专用队列。
- 一旦完成,它就会提交所有内容。触发器生成的消息被丢弃。此时触发器激活消息可用于处理。
- 激活 MDB 的触发器获取激活消息,然后在业务队列上重新打开队列部门触发器,以便整个过程可以再次启动。
在大多数情况下一切正常。然而,我们偶尔会在死信队列中收到一些消息,这会导致我们的监控工具呼叫支持。检查 DLQ 中的消息,我们注意到它们是触发器生成的消息,发送到 DLQ 的原因是启动队列已满(记住我们的最大一条消息限制)。
我们没有解释这是怎么可能的。 IBM 文档说在发送第一个触发器生成的消息后触发被关闭,但是从我们正在试验的内容来看,它看起来像是第一个触发器生成的消息得到处理并且处于未提交状态,第二个触发器生成的消息被创建并发送到启动队列。无法传递它(因为最大部门 = 1 限制)它会将它发送到死信队列。
任何关于为什么这可能以及如何绕过它的意见都将非常受欢迎。 2:00AM 的虚假支持电话肯定不好笑。
提前感谢您的意见。
我们的问题的解释在 IBM MQ 触发文档上,我们应该更仔细地阅读 IBM note:
注意:如果您停止并重新启动队列管理器,TriggerInterval 计时器将被重置。有一个小 window 期间可以产生两个触发消息。 window 当队列的触发器属性设置为在消息到达的同时启用并且队列之前不是空的 (MQTT_FIRST) 或具有 TriggerDepth 或更多消息 (MQTT_DEPTH).
一旦我们得到解释,解决方案就很简单了。我们没有将业务队列配置为将触发器生成的消息直接发送到启动队列,而是将其配置为发送到设置了最大队列部门限制的不同队列。然后我们实现了另一个 MDB 来获取这些触发器生成的消息并将它们重定向到启动队列。由于现有队列部门限制,无法将触发器生成的消息传递到启动队列而导致的任何异常都已实现此 MDB。
换句话说,对于这个新的 MDB,我们承担了从我们手中的 MQ 管理器传递触发器生成的消息的角色,并使该过程忽略由队列部门引起的任何传递失败。
我们有一个 HA 应用程序,它在指向同一个队列管理器的几台服务器上运行。因为消息排序很重要,所以我们使用信号量队列来确保不会有两个应用程序从业务队列中读取消息,即使该队列上有多个消息等待处理也是如此。
工作流程如下:
- 业务队列设置了一个MQTT_DEPT触发器,当队列部门等于一个 时触发
- 业务队列接收一个或多个消息。
- 当队列部门变成一个并将触发器消息放入启动队列时触发器启动。
- 作为队列部门触发器,它应该在将触发器消息传递到启动队列后自行关闭
- 有一个 MDB 正在侦听获取触发消息的启动队列
- 因为顺序对我们来说至关重要,所以我们对启动队列进行了限制,使其最大队列部门为 1。这样一次只有一个 MDB 可以获取消息
- 当触发器消息到达时,MDB 会去读取业务队列中的所有消息,完成后它会将触发器激活消息发送到专用队列。
- 一旦完成,它就会提交所有内容。触发器生成的消息被丢弃。此时触发器激活消息可用于处理。
- 激活 MDB 的触发器获取激活消息,然后在业务队列上重新打开队列部门触发器,以便整个过程可以再次启动。
在大多数情况下一切正常。然而,我们偶尔会在死信队列中收到一些消息,这会导致我们的监控工具呼叫支持。检查 DLQ 中的消息,我们注意到它们是触发器生成的消息,发送到 DLQ 的原因是启动队列已满(记住我们的最大一条消息限制)。
我们没有解释这是怎么可能的。 IBM 文档说在发送第一个触发器生成的消息后触发被关闭,但是从我们正在试验的内容来看,它看起来像是第一个触发器生成的消息得到处理并且处于未提交状态,第二个触发器生成的消息被创建并发送到启动队列。无法传递它(因为最大部门 = 1 限制)它会将它发送到死信队列。
任何关于为什么这可能以及如何绕过它的意见都将非常受欢迎。 2:00AM 的虚假支持电话肯定不好笑。
提前感谢您的意见。
我们的问题的解释在 IBM MQ 触发文档上,我们应该更仔细地阅读 IBM note:
注意:如果您停止并重新启动队列管理器,TriggerInterval 计时器将被重置。有一个小 window 期间可以产生两个触发消息。 window 当队列的触发器属性设置为在消息到达的同时启用并且队列之前不是空的 (MQTT_FIRST) 或具有 TriggerDepth 或更多消息 (MQTT_DEPTH).
一旦我们得到解释,解决方案就很简单了。我们没有将业务队列配置为将触发器生成的消息直接发送到启动队列,而是将其配置为发送到设置了最大队列部门限制的不同队列。然后我们实现了另一个 MDB 来获取这些触发器生成的消息并将它们重定向到启动队列。由于现有队列部门限制,无法将触发器生成的消息传递到启动队列而导致的任何异常都已实现此 MDB。
换句话说,对于这个新的 MDB,我们承担了从我们手中的 MQ 管理器传递触发器生成的消息的角色,并使该过程忽略由队列部门引起的任何传递失败。