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