我目前正在将 JMS 支持添加到类似应用程序服务器的框架中。 JMS 将由 HornetQ(独立代理,服务器类路径上的 hornetq jar)实现,但既没有 JBoss,也没有 spring,也没有其他任何可以提供 MDB 的东西。
下一步是将消息监听器添加到 xa 队列,以允许并行处理传入消息。有些消息会启动长时间运行的任务,因此基本思想是从 onMessage
方法生成工作线程。
在漫长的互联网旅程中,我遇到了 this discussion ,其中一位参与者提到,他不会这样做,而是使用一个额外的内部队列来完成任务:然后(单线程)消息监听器将简单地从入站队列中获取消息并为内部队列创建新消息,其中在该内部队列的另一端,一些工作线程争夺传入的消息。一旦入站消息被“复制”到内部队列(这对我来说没问题),它们就会被确认。
不幸的是,他们没有说明为什么最好不要从 onMessage
方法中生成工作线程 - 也许是因为如果所有线程都来自游泳池很忙。所以我正在寻找设计决策的利弊:
- 从消息监听器的 onMessage 方法启动工作线程
- 使用内部队列“向工作线程发送消息”
最佳答案
撇开事务限制不谈,是否让多个线程(或进程)从队列中读取数据仅取决于消息顺序是否重要。显然,如果顺序很重要,那么单个线程自然会维护该顺序,而多个线程则不会提供此类保证。
您通常会发现,顺序很重要,但只适用于所有消息的一个子集。在这种情况下,如果单个线程性能不佳,您需要将这些消息从队列中取出并在尽可能短的时间内重新排队,因为要保留顺序,您必须使用单个线程从初始读取queue - 因此使用一个或多个内部队列。这导致的问题是事务将在消息完全处理之前关闭,因此您需要某种临时存储以确保如果进程在处理发生之前失败,消息不会被丢弃。
如果正如您的问题所暗示的那样,您不太担心丢弃消息,那么 java.util.concurrent.BlockingQueue
听起来就像您需要的内部队列,每个队列都有一个线程服务.
关于java - JMS 队列上多线程消息处理的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13936914/