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

6
我正在为一个类似应用服务器的框架添加JMS支持。 JMS将由HornetQ实现(独立代理,服务器类路径上的hornetq jars),但既没有JBoss也没有Spring,也没有提供MDBs的其他内容。
下一步是向xa队列添加消息侦听器,以允许并行处理传入消息。 有些消息会初始化长时间运行的任务,因此基本想法是从onMessage方法中生成工作线程。
在我漫长的互联网之旅中,我遇到了这个this discussion,其中一位参与者提到他不会这样做,而是使用额外的内部队列来处理任务:(单线程)消息侦听器将简单地从入站队列中抓取消息,并为内部队列创建新的消息,在该内部队列的另一端,一些工作线程争夺传入的消息。 然后,一旦将入站消息“复制”到内部队列中(对我来说没问题),就会确认入站消息。

不幸的是,他们没有说明为什么最好不从onMessage方法中生成工作线程 - 可能是因为如果池中所有线程都忙碌,监听器会被阻塞。因此,我正在寻找设计决策的优缺点:

  • 从消息侦听器的onMessage方法启动工作线程
  • 使用内部队列将消息“发送到工作线程”
1个回答

3
除了交易限制之外,是否有多个线程(或进程)从队列中读取数据只取决于消息顺序是否重要。显然,如果顺序很重要,那么单个线程自然会维护顺序,而多个线程不会提供这样的保证。
通常情况下,您会发现阅读一部分消息时顺序很重要。在这种情况下,如果单个线程没有表现出色,您需要尽可能快地将这些消息从队列中删除并重新排队,以便保留顺序,您必须使用单个线程从初始队列中读取 - 因此需要使用一个或多个内部队列。这会带来的问题是,在处理完成之前,事务将关闭,因此您需要某种临时存储来确保处理过程还未完成就不会丢失消息。
如果像您的问题所示,您不太担心丢失消息,则java.util.concurrent.BlockingQueue听起来就是您需要的用于内部队列,每个服务一个单独的线程。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接