我有一个spring应用程序,我想使用JMS Message Groups来处理特定块中的JMS消息(以及相同的事务等)。基本上我说我有5个相关事件,我有一个JMSTemplate
,它们使用相同的JMSXGroupID
和顺序JMSXGroupSeq
值发送它们。
然后我在Spring中定义了MessageProcessorService
看起来像这样:
<bean id="messageProcessorService" class="x.y.z.MessageProcessorService"/>
<jms:listener-container connection-factory="pooledJmsConnectionFactory" concurrency="5" >
<jms:listener destination="messages.queue" ref="messageProcessorService" />
</jms:listener-container>
我的MessageProcessorService
是标准的,简单的:
@Service
public class MessageProcessorService implements MessageListener {
public void onMessage(Message msg) { ... }
}
问题是,因为onMessage只能获得1条消息。如何获取特定组中的所有5条消息,然后开始处理它们?
我知道我可以使用负JMSXGroupSeq
值来标记组的结尾,然后我想我可以保留一小部分消息并检查消息JMSXGroupSeq
以及何时消息-1然后处理整个组,但这似乎有点hacky并且不确定它是否是线程安全的(我肯定需要并行处理多个线程)。
其他人在Spring / JMS / ActiveMQ之前做过类似的事情吗?
答案 0 :(得分:1)
为了回答我自己的问题,我找到了this approach并做了大致相似的事情。虽然不是很漂亮。我认为从长远来看,我们可能不得不放弃MessageListenerContainer并使用直接JMS api推出我们自己的解决方案。
答案 1 :(得分:0)
好问题。虽然消息组对某些任务很有用,但它们并没有将这些好处映射到消息监听器上。
您可以采用自己的方法,在邮件的内存中保留一个列表。如果在原型范围中创建Listener bean,则线程安全性不会成为问题。
<bean id="messageProcessorService" class="x.y.z.MessageProcessorService" scope="prototype"/>
您只需要保留在课程中收到的一些内部消息列表,它们对于该线程将是唯一的。
这取决于您的交易要求。您是否需要围绕整个消息组提交事务?然后你需要跟踪何时提交以及何时提交。 IBM已经在清单5中举例说明了这一点(尽管不使用ActiveMQ)here。它不是Spring而是普通的MDB。不能说它与ActiveMQ的工作原理相同,所以我不保证。