[英]Guaranteed Delivery with JMS topics and ActiveMQ Artemis
I'm discovering the whole JMS world, and for now every time I have tried to use a topic (pub/sub) I ultimately switched to a queue and either used a recipient-list pattern or directly performed the various computations in the consumer (which transaction-wise is not ideal, but I'm not sure if defining plenty of queues is a better practice).我正在探索整个 JMS 世界,现在每次我尝试使用一个主题(pub/sub)时,我最终都切换到一个队列,要么使用收件人列表模式,要么直接在消费者中执行各种计算(哪种事务方式并不理想,但我不确定定义大量队列是否是一种更好的做法)。
I need to be sure all subscribers will get all the messages, and as I configured it that doesn't seems to be compatible with topics.我需要确保所有订阅者都会收到所有消息,并且当我配置它时,它似乎与主题不兼容。
I'm using an embedded ActiveMQ Artemis configuration (so no console, which doesn't help debugging), and Spring JMS.我正在使用嵌入式 ActiveMQ Artemis 配置(因此没有控制台,这无助于调试)和 Spring JMS。 My
broker.xml
looks as follow:我的
broker.xml
如下所示:
<configuration
xmlns="urn:activemq"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:activemq /schema/artemis-server.xsd">
<jms xmlns="urn:activemq:jms">
</jms>
<core xmlns="urn:activemq:core">
<persistence-enabled>true</persistence-enabled>
<security-enabled>false</security-enabled>
<acceptors>
<acceptor name="in-vm">vm://0</acceptor>
</acceptors>
<address-settings>
<address-setting match="#">
<!-- all queues have redelivery -->
<redelivery-delay>200</redelivery-delay>
<max-redelivery-delay>60000</max-redelivery-delay>
<redelivery-delay-multiplier>1.5</redelivery-delay-multiplier>
<redelivery-collision-avoidance-factor>0.15</redelivery-collision-avoidance-factor>
<!-- all queues have dead-letters -->
<max-delivery-attempts>10</max-delivery-attempts>
<auto-create-dead-letter-resources>true</auto-create-dead-letter-resources>
</address-setting>
</address-settings>
</core>
</configuration>
My jmsListenerContainerFactory
is defined as follow:我的
jmsListenerContainerFactory
定义如下:
DefaultJmsListenerContainerFactory listenerContainerFactory = new DefaultJmsListenerContainerFactory();
listenerContainerFactory.setConnectionFactory(aConnectionFactory);
listenerContainerFactory.setDestinationResolver(aDestinationResolver);
listenerContainerFactory.setSessionTransacted(true);
listenerContainerFactory.setSessionAcknowledgeMode(JMSContext.SESSION_TRANSACTED);
listenerContainerFactory.setMessageConverter(aMessageConverter);
listenerContainerFactory.setTransactionManager(aTransactionManager);
return listenerContainerFactory;
My consumers are @Jmslistener
annotated methods in various classes (sometime multiple for one topic in the same class if that matters).我的消费者是各种类中的
@Jmslistener
注释方法(如果重要的话,有时对于同一个 class 中的一个主题有多个)。
It seems to me as if the messages are not always sent to all the consumers.在我看来,消息似乎并不总是发送给所有消费者。 Or as if the consumers would disconnect themselves from the topic while processing a message.
或者好像消费者在处理消息时会断开与主题的连接。
The behavior is consistent and happens 100% of the time on a test.行为是一致的,并且在测试中 100% 发生。
Did I missed something big, or aren't topics meant for reliable communication?我是否错过了一些重要的事情,或者主题不是为了可靠的沟通?
What you're seeing is the expected behavior.您所看到的是预期的行为。 Generally speaking, a subscriber has to be connected to the broker in order to receive messages.
一般来说,订阅者必须连接到代理才能接收消息。 This is traditional publish/subscribe semantics.
这是传统的发布/订阅语义。
You can change this behavior by using a durable subscription (use setSubscriptionDurable(true)
on your instance of DefaultJmsListenerContainerFactory
).您可以通过使用持久订阅来更改此行为(在您的
DefaultJmsListenerContainerFactory
实例上使用setSubscriptionDurable(true)
)。 However, this can be problematic if subscribers disconnect for an extended period of time as messages will accumulate in their subscriptions.但是,如果订阅者长时间断开连接,这可能会出现问题,因为消息会在他们的订阅中累积。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.