JMS队列上多线程消息处理的最佳实践

时间:2012-12-18 16:05:13

标签: java queue jms message-listener

我目前正在向类似应用程序服务器的框架添加JMS支持。 JMS将由HornetQ(独立代理,服务器类路径上的hornetq jars)实现,但既没有JBoss也没有spring,也没有任何其他东西可以提供MDB。

下一步是将消息侦听器添加到xa队列,以允许并行处理传入消息。有些消息会初始化长时间运行的任务,因此基本思路是从onMessage方法生成工作线程。

在我漫长的互联网旅程中,我遇到this discussion,其中一位参与者提到,他不会这样做但是使用额外的内部队列来完成任务:(单线程)消息监听器然后会只需从入站队列中获取消息并为内部队列创建新消息,在该内部队列的另一端,某些工作线程会为传入消息进行争用。一旦它们被“复制”到内部队列(这对我来说没问题),入站消息就会被确认。

不幸的是,他们没有说为什么最好不从onMessage方法生成工作线程 - 也许,因为如果池中的所有线程都忙,则监听器会阻塞。所以我正在寻找设计决策的利弊:

  • 从消息侦听器的onMessage方法启动工作线程
  • 使用内部队列“向工作线程发送消息”

1 个答案:

答案 0 :(得分:3)

除了交易限制之外,是否有多个线程(或进程)从队列中读取只是归结为消息顺序是否重要。显然,如果订单很重要,那么单个线程自然会维护该订单,而多个线程则不会提供这样的保证。

您通常会发现,订单很重要,但是在所有邮件的子集中。在这种情况下,如果单个线程不具有性能,则需要将这些消息从队列中取出并在尽可能短的时间内重新排队,因为要保留顺序,您必须使用从初始读取的单个线程queue - 因此使用一个或多个内部队列。这导致的问题是,在完全处理消息之前,事务将被关闭,因此您需要某种临时存储,以确保在处理发生之前进程崩溃时不会丢弃消息。

如果你的问题表明,你并不太担心丢弃消息,那么java.util.concurrent.BlockingQueue听起来就像内部队列所需要的那样,只需要一个线程为每个队列提供服务。