多线程JMS消息消耗



我需要同时使用队列中的消息。幸运的是,消息的顺序并不重要。

我已经想出了一个解决方案,但我不确定它有多正确。该解决方案在多个线程中消耗消息,重用它们,并最终杀死线程。但是,像这样使用消息不是不安全吗?

此外,当前的解决方案使用AUTO_ACKNOWLEDGE,理想情况下,我希望用CLIENT_ACKNOWLEDGE替换它。不幸的是,由于我使用的是一个会话,所有的消息都会同时得到确认,所以似乎没有简单的方法可以做到这一点。ActiveMQ Artemis没有类似于ActiveMQ的CCD_ 3的选项;经典;做

有人对这个解决方案是否可行有任何想法吗?和/或对如何改进这个解决方案以便我可以使用CLIENT_ACKNOWLEDGE有任何想法?

private void createConsumer(Connection connection, String queueName, int maxPoolSize) {
try {
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue(queueName);
MessageConsumer messageConsumer = session.createConsumer(queue);
ThreadPoolExecutor executor = new ThreadPoolExecutor(
0, maxPoolSize,
60L,
TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
messageConsumer.setMessageListener(message -> {
try {
executor.submit( () -> {
messageHandler.handleMessage(message);
});
message.acknowledge();
} catch (JMSException e) {
e.printStackTrace();
}
});
} catch (JMSException e) {
e.printStackTrace();
}
}

ActiveMQ Artemis确实为消费者提供了INDIVIDUAL_ACKNOWLEDGE模式。您只需要使用文档中提到的ActiveMQJMSConstants.INDIVIDUAL_ACKNOWLEDGE

此外,基本上唯一真正线程安全的JMS对象是javax.jms.Connection,因此您不能同时使用会话、使用者、生产者等。然而,在您的代码中,您实际上并没有同时使用其中的任何一个。

也就是说,你仍然只是在这里创建一个单个消费者。我认为,如果您只创建多个会话、消费者、监听器等,您会获得更好的性能,也许还会获得更简单的代码。客户端实现将负责在消息到达时在自己的线程中调用每个监听器,这样您就不必自己管理任何线程。

最新更新