首先发送消息到达2个队列中的一个

时间:2014-09-10 15:37:28

标签: jms ibm-mq

我有一个应用程序,我想要消耗来自队列A的消息,但如果队列A为空,我希望它消耗来自队列B的消息而不是闲置。我只希望它一次处理1条消息,如果消费者忙于处理消息(来自任一队列),其他待处理消息(在任一队列上)应保留在其队列中,直到消费者再次空闲为止(这给出其他消费者有机会处理新消息。)

因此,例如,如果消息在空闲(等待)时消息到达队列A或队列B,则消费者将其选中。如果消费者当前处理消息时消息到达任一队列,则在消费者处理完当前消息之前不会发生任何事情。如果队列A和队列B上都有消息,则消费者更喜欢从队列A中选择消息。

修改:实际上我很高兴被告知可以在A& A上使用消息。 B,并实现我自己的逻辑,以选择我真正想从队列中提取哪一个。

在单独的线程中同时订阅这两个队列并不会起作用,因为:

  • 如果消息 M 到达队列A,则消费者在处理消息 M 时必须取消订阅队列B,然后重新订阅消息< em> M 被处理。除此以外, 如果消息到达队列B,它可能会被同时发送和发送 - 我不想一次处理多条消息。
  • 如果消息一次到达两个队列(或者当消费者启动或完成处理前一个消息时消息已经在两个队列上都可用),则可能之前两个消息都被拾取消费者有机会取消订阅队列B.如果发生这种情况,我必须回滚其中一条消息,但如果经常发生这种情况,消息将超过回滚计数并转移到故障队列。

理想情况下,我想将此概括为N队列案例。我对通过JMS理想工作的解决方案感兴趣,但是如果我必须使用IBM MQ特定的API来做到这一点也可以。是否有使用模式或库可以帮助实现这一目标?是否有允许它的替代排队方法/技术/技术?

从所有队列中拉出所有消息并将它们放在一个队列上是不行的;我们需要能够独立清除各个队列,不同的消费者可以订阅N个队列的不同子集。

3 个答案:

答案 0 :(得分:2)

我不知道这对您的代码是否会发生重大变化,但您是否想过在项目中添加Spring Framework,特别是Spring Integration?您描述的问题已在那里处理。

这个问题可以通过两个端点和两个队列上的事件驱动的使用者和一个线程池来解决。

http://www.eaipatterns.com/EventDrivenConsumer.html

http://en.wikipedia.org/wiki/Thread_pool_pattern

[编辑]

如果您希望邮件保留在队列中,直到线程被释放,您可以遵循轮询使用者的模式

http://www.eaipatterns.com/PollingConsumer.html

可以根据需要从哪个队列中选择首先请求消息。请记住,使用此技术,如果您的系统处理的邮件速度快于到达,您将会遇到对队列的一些冗余轮询。

答案 1 :(得分:1)

如果我打算编写这个应用程序,我想我会使用异步消费者。我会在同一个连接句柄(hConn)上使用MQCB动词设置两个使用者,因此一次只能驱动一个。然后用MQCTL启动消费者来设置事情。

当您在回调函数中处理消息时,不会再使用来自任一队列的消息驱动消息。

要回答您的其他问题 - 如果两条消息同时到达,则无法保证始终优先驱动队列A的回叫。显然,如果消息在队列B上比队列A提前一瞬间到达队列B,则您的要求是在队列B上处理消息。因此,如果您在一个消息之前处理队列B上的一条消息,这确实会引起问题。队列A在完全同时到达时。

我从你的问题编辑中看出,你很高兴只是收到有关已经到达的消息的通知,然后你可以自己去做。您还可以在浏览模式下使用Async Consume,这意味着只要消息到达队列就可以调用,然后在回调函数中,您可以发出MQGET来检索具有破坏性获取的实际消息。

然后,您可以让Queue B的回调函数始终在队列A上执行快速无等待MQGET调用,然后再选择处理它自己的消息来处理优先要求。这会有点低效,但肯定比轮询两个队列更好,因为这会增加你绝对不想要的等待间隔。这种低效率是否值得,取决于你对其重要性的回答。

队列A的回调函数可以直接处理消息。

答案 2 :(得分:1)

我对这个问题的第一反应是将队列处理外包给Windows服务(假设你在Windows服务器上运行它)。我不认为你能在MQ本身内完全做到这一点。

将每个队列的触发设置为First,并让触发的应用程序连接到服务,并提供有关它所代表的队列的信息,然后终止。然后,服务将根据您为其设置的任何规则处理每个队列。

根据评论中的问题修改答案:

  1. 在MQ本身内&#34;&#34;我的意思是描述功能可能不是你可以通过MQ组件上的任何设置完成的,例如队列管理器,通道,队列等。您必须在MQ之外设置某种服务应用程序才能执行此操作。

  2. &#34;为什么它是服务,常规控制台应用程序还是GUI?&#34;它可能并不重要,但Windows服务始终处于打开状态,无需用户干预即可运行,并且可以与其他有人参与和无人值守的应用程序进行交互。控制台应用程序或GUI可能能够执行其中某些操作,但它们并非专为此设计,并且可能无法始终如一地工作。另一方面,如果您必须与它进行交互,显然GUI或控制台应用程序将是最佳选择。但是,我实际上并不知道你要做什么,所以我的想法可能完全不适合你。

  3. &#34;我不熟悉触发 - 你在谈论这个吗?&#34;是。我已经使用Websphere MQ多年了,而且我几乎在每个应用程序中都使用了触发器。

  4. 如果您正在使用GUI,那么您可能想要轮询各个队列以查看它们的内容并将它们排列在您的GUI中以供使用,我的建议都没有和你有任何关系。我假设无人值守的操作,所以我们就是这样。