首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >带第一条消息到达两个队列中的一个

带第一条消息到达两个队列中的一个
EN

Stack Overflow用户
提问于 2014-09-10 15:37:27
回答 3查看 450关注 0票数 3

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

因此,例如,当使用者空闲(等待)时,如果消息到达队列A或队列B,则使用者将取起它。如果在使用者当前处理消息时,消息到达任一队列,则在使用者完成当前消息处理之前,不会发生任何事情。如果队列A和队列B都有消息可用,则使用者更愿意从队列A中选择消息。

编辑:实际上,我同样乐意被告知消息可以在A& B上使用,并实现我自己的逻辑来选择我实际上想要从队列中提取的消息。

在单独的线程中同时订阅两个队列似乎无法工作,因为:

  • 如果消息M到达队列A,则在处理消息M时,使用者必须从队列B取消订阅,然后在消息M被处理后重新订阅。否则,如果一条消息到达队列B,它可能会同时被接收和发送--我不想一次处理多条消息。
  • 如果一条消息同时到达两个队列(或者当使用者启动或完成对前一条消息的处理时,两个队列上都已经有一条消息可用),那么在使用者有机会取消订阅队列B之前,可能会捕获两条消息。如果出现这种情况,我将不得不回滚其中一条消息,但如果这种情况经常发生,则消息将超过回滚计数并移到失败队列。

理想情况下,我想将其概括为N个队列的情况。我对理想情况下通过JMS工作的解决方案很感兴趣,但是如果我必须使用特定于IBM的API来实现这一点,那也没关系。是否有有助于实现这一目标的使用模式或库?是否有其他允许排队的方法/技术/技术?

将所有消息从所有队列中取出并放到单个队列中是不可能的;我们需要能够独立地清除单个队列,不同的使用者可能订阅N队列的不同子集。

EN

回答 3

Stack Overflow用户

发布于 2014-09-10 19:09:30

我不知道这对您的代码是否是一个很大的改变,但是您是否考虑过在您的项目中添加Spring框架,特别是Spring集成?您所描述的这些问题已经在那里处理过了。

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

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

pattern

编辑

如果您希望消息保持在队列中直到线程被释放,则可以遵循轮询使用者的模式。

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

它可以根据您的意愿选择哪个队列首先请求消息。请记住,使用此技术,如果您的系统处理消息的速度比消息到达的速度快,您将体验到队列中的一些冗余轮询。

票数 2
EN

Stack Overflow用户

发布于 2014-09-15 10:31:58

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

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

要回答您的附加问题--如果两个消息同时到达,则无法保证队列A的回调总是优先驱动的。显然,如果消息到达队列B的时间比队列A早一秒,那么您的要求是处理队列B上的消息。因此,这就产生了一个问题:如果您在队列B上处理一条消息而不是在队列A上处理一条消息,那么当消息同时到达时,为什么重要。

我从你在问题中的编辑中看到,你很高兴得到消息的通知,然后你可以自己去做。您还可以在浏览模式中使用异步消费,这意味着每当消息到达队列时都可以调用您,然后在回调函数中您可以发出MQGET来使用破坏性的get检索实际消息。

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

尽管如此,Queue A的回调函数可以直接处理消息。

票数 1
EN

Stack Overflow用户

发布于 2014-09-15 17:18:47

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

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

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

  1. 所谓“在MQ本身中”,我的意思是描述功能可能不是通过对MQ组件(如队列管理器、通道、队列等)的任何设置来完成的。为了做到这一点,您必须在MQ之外设置某种服务应用程序。
  2. “为什么它是一个服务、一个常规控制台应用程序还是一个GUI?”这可能并不重要,但Windows服务总是开着的,在不需要用户干预的情况下运行,并且可以与其他参与和无人参与的应用程序进行交互。控制台应用程序或GUI可能能够完成其中的一些工作,但它们并不是为其设计的,而且可能无法一致工作。另一方面,如果您必须与它交互,显然,GUI或控制台应用程序将是前进的道路。不过,我不知道你到底想做什么,所以我的想法对你来说可能完全落伍了。
  3. “我不熟悉触发--你是在说这个吗?”是。多年来,我一直在使用Websphere MQ,并且几乎在每个应用程序中都使用了触发。

如果您正在使用GUI,那么您可能希望轮询各种队列,看看它们有哪些,并将它们排入要处理的GUI中,而我的建议与您没有任何关联。我以为是无人值守的手术,所以我们到了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25769559

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档