0
votes

I'm investigating ActiveMQ to see if it will work for a project. The current use case I need to demonstrate is that late-joining subscribers will receive topics published prior to the creation of the subscription. It seemed that ActiveMQ Retroactive Consumers would satisfy this need, but I can't get the code to work.

ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("[url]");
Connection connection = connectionFactory.createConnection();
connection.start();

Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

Destination destination = session.createTopic("testAddress?consumer.retroactive=true");

MessageProducer producer = session.createProducer(destination);

TextMessage message = session.createTextMessage("Hello, World!");

producer.send(message);

Thread.sleep(5000);

session.createConsumer(destination).setMessageListener(message2 -> processMessage(message2));

session.close();
connection.close();
connectionFactory.close();

All I'm trying to demonstrate here is that a topic can be published, and then some arbitrary amount of time later (eg. 5 seconds) a consumer can subscribe to the topic and receive the previous message.

As far as I can tell, the issue seems to be that creating the topic creates an address but doesn't create any associated queues. If I send a topic to the address before the queue is made (either in code or manually via the web interface to the broker), the message seems to be ignored and the "un routed message count" is immediately incremented.

The ActiveMQ documentation ( https://activemq.apache.org/retroactive-consumer ) doesn't provide any greater detail on how to set up a retroactive consumer than appending "?consumer.retroactive=true" when making the topic, so I wonder if there are some other configuration aspects I'm missing.

2
Are you use ActiveMQ 5.x or an ActiveMQ Artemis broker instance, the comments make it unclear which - Tim Bish
@TimBish ActiveMQ Artemis. As far as I can tell from the documentation it shouldn't make a difference. - MattS
Whether you're using ActiveMQ 5.x or ActiveMQ Artemis does, in fact, make a big difference. The documentation you've linked is for 5.x (which is available from here). The documentation for Artemis is available from here. - Justin Bertram
Also, for what it's worth you can set the send-to-dla-on-no-route address setting to true and define a dead-letter address with a dead-letter queue to capture messages sent to an address with no subscribers. It won't give you behavior equivalent to a retro-active consumer, but it will preserve those messages nonetheless which might be helpful in your overarching use-case. - Justin Bertram

2 Answers

2
votes

To my knowledge ActiveMQ Artemis doesn't support the retroactive consumer feature that 5.x does. The client side option just tells the broker you want it, but since Artemis doesn't handle that you won't see any difference from sending it. The feature itself in 5.x shouldn't be relied upon as a 100% stand in for a durable consumer, broker restart for instance will cause all those messages (of which the amount stored is finite) to be lost.

If you want to guarantee that you get messages sent when the topic consumer is offline then a durable consumer is the safe way to do this

0
votes

To accomplish the desired behavior (a subscriber receives topics that were published before the subscription was made) in ActiveMQ Artemis, I used a Last Value Queue with non-destructive reads. This has the limitation that I'm only receiving only the most recent copy of a topic published, but that will work for my situation.