Apache ActiveMQ Artemis Durable Subscription TTL - jms

I would like to configure a durable topic, but I want to configure how long Apache ActiveMQ Artemis will hold onto a message for an inactive durable subscriber to the topic.
For example, something like "Save durable messages for up to 30 seconds for inactive durable subscribers". If the subscriber does not become active within 30 seconds, the message is no longer available for them when they do become active.
Is this something that can be done? If not, does Artemis or JMS provide an alternative way to accomplish this or something similar.

ActiveMQ Artemis doesn't have exactly the functionality you're looking for, but you can get close using the expiry-delay address-setting which will apply an expiration time to message which don't already have their expiration time set. See the configuration details in the documentation. This will ensure that messages expire rather than accumulating in the inactive durable subscription.

Related

How to set expiry for specific ActiveMQ queue

the documentation of ActiveMQ is giving me a hard time so you are my last hope :D
What i want:
An expiration date on messages in the outgoing queue. Messages in the incoming, DLQ and RTS Queue should stay for ever.
So expiration is always 0 except when a message is put in the outgoing queue. Then ActiveMQ has to set a new expiration day. Alternatively this could also be set by the Application
Or alternatively (maybe easier):
An expiration date on messages in the outgoing and incoming queue. Messages in the DLQ and RTS Queue should stay for ever.
So expiration is always 12345 (or so) except when a message is transfer to RTS or DLQ. Then ActiveMQ has to set the new expiration day to 0
What i tried:
Setting an expiry date for the outgoing messages explicitly in the
application message.setJMSExpiration(XYZ); however, the
expiration date was then always set to 0. Probably because of the
spring jms lib
Configure the deadLetterStrategy so all messages in the DLQ get a expiration of 0. But seems to have no effect. probably misconfigured
<deadLetterStrategy>
<individualDeadLetterStrategy
processNonPersistent="true"
queuePrefix="DLQ."
useQueueForQueueMessages="true"
processExpired="false"
expiration="0"/>
</deadLetterStrategy>
Maybe you can help me :)
Thank you in advance
Spring-jms:5.3.20
ActiveMQ:5.15.15
The JMS Message setJMSExpiration is explicitly documented as bit being meant for use by the user so that explains why calling it isn't working for you.
This method is for use by JMS providers only to set this field when a message is sent. This message cannot be used by clients to configure the expiration time of the message. This method is public to allow a JMS provider to set this field when sending a message whose implementation is not its own.
To define a time to live for the message you either need to use the JMS Producer method setTimeToLive or the send method that allows you to provide the TTL value on a per message basis.
Alternatively you can configure the ActiveMQ Timestamp Plugin to apply a TTL value to each incoming message.
If you want expired messages to go into the DLQ then I'd suggest not configuring the broker to not do that as you've done above by setting processExpired="false" as that is specifically telling the broker not to DLQ expired messages.

How to clear messages from a JMS Topic based on age of messages

We have an application that publishes event notifications to a JMS Topic. The issue noticed here is that after a considerable amount of time, the message store in Weblogic reaches more that 10GB in size. Is there a way to implement a component that can remove messages from a JMS Topic which have crossed a certain age (say 30 days)?
Currently in place is a process, during downtime activity the message store is deleted. The process however, has a prerequisite check from the owners of the subscribing applications whether actions based on last message have been processed or not.
Thanks
Message accumulation for a JMS topic indicates there is at least one inactive durable subscription or perhaps slow subscription consumers. In general, you can prevent this by removing inactive durable subscriptions, speeding up slow subscription consumers, slowing down message production so that consumers can keep up, etc.
If you don't want to retain messages older than 30 days then you can try using the "Message Time-To-Live" functionality defined by the JMS specification. Section 4.8 of the JMS 1.1 spec states:
A client can specify a time-to-live value in milliseconds for each message it
sends. This value defines a message expiration time that is the sum of the
message’s time-to-live and the GMT it is sent (for transacted sends, this is the
time the client sends the message, not the time the transaction is committed).
A JMS provider should do its best to expire messages accurately; however, JMS
does not define the accuracy provided. It is not acceptable to simply ignore
time-to-live.
For more information on message expiration, see Section 3.4.9
"JMSExpiration."
The message's time-to-live can be set when the message is sent using either javax.jms.MessageProducer.setTimeToLive(long) or one of the overloaded send() methods. This will, of course, require changing the sending application's code.
Many brokers support setting the message's time-to-live or expiration time on the broker so that client modifications aren't strictly necessary. I'm not familiar enough with Weblogic to know if it supports this functionality or not, but it's worth investigating if you want to use this solution and don't want to modify your clients.
Came across the following code, which can help in clearing the messages by browsing thru the queue.
queue browser

JMS QPID Queue vs Topic

I'm confused when it comes to JMS Queue/Topic. What I want is messages should go to every subscriber and I want subscribers to receive messages from inactive time when they become active. However, I don't have control over whether or not subscribers have durable subscription. Is there a way to set up a persistent Queue, and set it up so that every subscriber will receive same message? And how to set this up using spring config
Thanks much.
This is mostly a question where the design of your system affects the outcome.
You could use UI tooling to create durable subscriptions for the clients that need to but that is cumbersome and error prone. You could use something like camel or other configuration on the target broker to fanout messages from an incoming Queue to outgoing Queues that map to the consumer subscriptions.
It all depends mostly on the requirements and your overall design so a real answer is beyond the scope of a SO answer without you doing some more legwork to narrow the scope a bit. JMS itself does not define any answer for this so it will come down a bit to the broker you've chosen and possibly other third party tooling that you might pick to do what you need.

ActiveMQ not delivering/dispatching persistent messages on queues

I am using ActiveMQ v5.10.0 and having an issue almost every weekend where my ActiveMQ instance stops delivering persistent messages sent on queues to the consumers. I have not been able to figure out what could be causing this.
While the issue was happening I tried following things:
I added a new consumer on the affected queue but it didn't receive
any messages.
I restarted the original consumer but it didn't receive any messages after the restart.
I purged the messages that were held on the queue but then messages started accumulating again and broker didn't deliver any of the new messages. When I purged the expiry count didn't increase neither the dequeue and dispatch counters.
I sent 100 non-persistent messages on the affected queue, surprisingly it received those messages.
I tried sending 100 persistent messages on that queue, it didn't deliver anyone of them, all the messages were held by broker.
I created a fresh new queue and sent 100 persistent messages and none of them was delivered to the consumer whereas all the non-persistent messages were delivered.
The same things happen if I send persistent or non-persistent messages from STOMP producers. Surprisingly all this happened only for queues, topic consumers were able to receive persistent as well as non-persistent messages.
I have already posted this on ActiveMQ user forum: http://activemq.2283324.n4.nabble.com/Broker-not-delivering-persistent-messages-to-consumer-on-queue-td4691245.html but no one from ActiveMQ has suggested anything.
The jstack output also isn't very helping.
More details:
1. I am not using any selectors, message groups feature
2. I have disabled producer flow control in my setup
I want some suggestions as to what configuration values might cause this issue- memory limits, message TTL etc.

Why are topic subscribers on the ActiveMQ admin UI constantly changing?

I have a JMS non-durable topic with multiple subscribers (using ActiveMQ).
Each subscriber is a web application deployed on a separate Tomcat instance.
When a message arrives, I want it delivered to all subscribers (somewhat of a distributed cache implementation).
I've noticed that not always the message gets delivered to all subscribers. When looking at the ActiveMQ admin UI I see the list of topic subscribers (as well as the list of connections) constantly changing. E.g. I see 17 subscribers, I refresh the ActiveMQ admin UI, then I see 19 subscribers, I refresh again - I see 18 etc.
What's wrong? I know that all the tomcats are up all the time. My understanding of JMS topics is that if the application is up, the message should always get delivered. Have I misunderstood something? I see no logical reason for this subscriber 'flashing'.
P.S. I'd rather not try durable topics - I don't need the message delivered if the application is not up.

Resources