我有这个问题,在我的队列中有来自不同源系统的消息。
例如:在第一条消息中,我的源系统名称为:'X',在第二条消息中,源系统名称为:'Y'。
目前我有一个JMS监听器,其并发级别设置为1.因此所有消息都按预期逐个处理,但现在我想同时处理消息,这样如果消息来自同一源系统,那么只有一条消息应该一次为该源系统处理,如果有不同源系统的消息,则必须并行执行。
源系统正在动态创建,这就是为什么我不能为每个源系统提供单独的队列和使用者。
如果有人把我推向正确的方向,那就太好了。
答案 0 :(得分:1)
听起来你的问题在于维护源自给定源的消息的有序传递,但是能够并行处理来自不同源的消息。
您可以使用message groups执行此操作。
代理允许消息传递应用程序对一组相关的进行分类 消息属于一个组。这允许消息生产者 向消费者表明应该考虑一组消息 关于应用程序的单个逻辑操作。
要使其工作,让生产者系统将JMSXGroupID标头设置为生产者系统名称:
Mesasge message = session.createTextMessage("<message />");
message.setStringProperty("JMSXGroupID", "SourceSystem1Name");
然后,代理将在属于该组的消息中强制执行消费排序。
<强>附录强>
创建时可能有N个源系统 动态地,有一个生产者放置所有的消息 这些N个源系统进入队列
因此消息生产者可以将JMSXGroupID标头设置为源系统的名称。
我面临的问题是如果一个源系统的消息是 处理后,其他源系统消息必须等到 完成对该消息的处理
因此,一旦按照描述设置了组头,代理就会确保它只按顺序向消费者发布给定源系统的消息。它通过强制消费者在发布组中的下一条消息之前发送已确认先前消息的确认来实现此目的。
因此,通过将并发设置为某个适当的值,使用者可以并行处理来自不同源系统的消息,但将被强制顺序处理来自任何给定源系统的消息,这是您需要的行为。
答案 1 :(得分:0)
因为消费者是在消费者一方宣布的,所以你不能动态地(据我所知)根据另一个变量对其进行更改。
我建议的解决方案是使用选择器并使用两个消费者连接,如下所示:
并行处理的消费者端点(本例中为5)将如下所示:
activemq:queue:MY_QUEUE_UNIQUE?concurrentConsumers=5&selector=MySourceHeader<>'X'
顺序处理的消费者端点如下:
activemq:queue:MY_QUEUE_UNIQUE?concurrentConsumers=1&selector=MySourceHeader='X'
为队列定义一个获取大小也是一件好事(即使我不确定它是强制性的)。