Messages can be set with an optional time to live when sending them.
Apache ActiveMQ Artemis will not deliver a message to a consumer after it’s time-to-live has been exceeded. If the message hasn’t been delivered by the time that time-to-live is reached the server can discard it.
Apache ActiveMQ Artemis’s addresses can be assigned an expiry address so that, when messages are expired, they are removed from the queue and sent to the expiry address. Many different queues can be bound to an expiry address. These expired messages can later be consumed for further inspection.
1. Core API
Using Apache ActiveMQ Artemis Core API, you can set an expiration time directly on the message:
// message will expire in 5000ms from now
message.setExpiration(System.currentTimeMillis() + 5000);
JMS MessageProducer allows to set a TimeToLive for the messages it sent:
// messages sent by this producer will be retained for 5s (5000ms) before expiration
producer.setTimeToLive(5000);
Expired messages get special properties plus this additional property:
- _AMQ_ACTUAL_EXPIRY
-
a Long property containing the actual expiration time of the expired message
2. Configuring Expiry Delay
There are multiple address-settings which you can use to modify the expiry delay for incoming messages:
-
no-expiry
-
expiry-delay
-
max-expiry-delay
&min-expiry-delay
These settings are applied exclusively in this order of precedence. For example, if no-expiry
is set and expiry-delay
is also set then expiry-delay
is ignored completely and no-expiry
is enforced.
If you set any of these values for the |
Let’s look at each of these in turn.
2.1. Never Expire
If you want to force messages to never expire regardless of their existing settings then set no-expiry
to true
, e.g.:
<!-- messages will never expire -->
<address-setting match="exampleQueue">
<no-expiry>true</no-expiry>
</address-setting>
For example, if no-expiry
is set to true
and a message which is using an expiration of 10
arrives then its expiration time of 10
will be changed to 0
.
The default is false
.
2.2. Modify Default Expiry
To modify the expiry delay on a message using the default expiration (i.e. 0
) set expiry-delay
, e.g.
<!-- expired messages in exampleQueue will be sent to the expiry address expiryQueue -->
<address-setting match="exampleQueue">
<expiry-address>expiryQueue</expiry-address>
<expiry-delay>10</expiry-delay>
</address-setting>
For example, if expiry-delay
is set to 10
and a message which is using the default expiration time (i.e. 0
) arrives then its expiration time of 0
will be changed to 10
.
However, if a message which is using an expiration time of 20
arrives then its expiration time will remain unchanged.
This value is measured in milliseconds. The default is -1
(i.e. disabled).
2.3. Enforce an Expiry Range
To enforce a range of expiry delay values
<address-setting match="exampleQueue">
<min-expiry-delay>10</min-expiry-delay>
<max-expiry-delay>100</max-expiry-delay>
</address-setting>
Semantics are as follows:
-
Messages without an expiration will be set to
max-expiry-delay
.-
If
max-expiry-delay
is not defined then the message will be set tomin-expiry-delay
. -
If
min-expiry-delay
is not defined then the message will not be changed.
-
-
Messages with an expiration above
max-expiry-delay
will be set tomax-expiry-delay
. -
Messages with an expiration below
min-expiry-delay
will be set tomin-expiry-delay
. -
Messages with an expiration within
min-expiry-delay
andmax-expiry-delay
range will not be changed.
These values are measured in milliseconds. The default for both is -1
(i.e. disabled).
Setting a value of |
3. Configuring Expiry Addresses
Expiry address are defined in the address-setting configuration:
<!-- expired messages in exampleQueue will be sent to the expiry address expiryQueue -->
<address-setting match="exampleQueue">
<expiry-address>expiryQueue</expiry-address>
</address-setting>
If messages are expired and no expiry address is specified, messages are simply removed from the queue and dropped. Address wildcards can be used to configure expiry address for a set of addresses.
If a wildcard is used to configure the expiry address for a set of addresses and you want to unset the expiry address for a particular addess (or set of addresses) then you can do so, e.g.:
<address-setting match="#">
<expiry-address>expiryQueue</expiry-address>
</address-setting>
<address-setting match="exampleQueue">
<expiry-address/> <!-- unset expiry-address so messages which expire from queues bound to matching addresses are dropped -->
</address-setting>
4. Configuring Automatic Creation of Expiry Resources
It’s common to segregate expired messages by their original address.
For example, a message sent to the stocks
address that expired for some reason might be ultimately routed to the EXP.stocks
queue, and likewise a message sent to the orders
address that expired might be routed to the EXP.orders
queue.
Using this pattern can make it easy to track and administrate expired messages.
However, it can pose a challenge in environments which predominantly use auto-created addresses and queues.
Typically administrators in those environments don’t want to manually create an address-setting
to configure the expiry-address
much less the actual address
and queue
to hold the expired messages.
The solution to this problem is to set the auto-create-expiry-resources
address-setting
to true
(it’s false
by default) so that the broker will create the address
and queue
to deal with the expired messages automatically.
The address
created will be the one defined by the expiry-address
.
A MULTICAST
queue
will be created on that address
.
It will be named by the address
to which the message was previously sent, and it will have a filter defined using the property _AMQ_ORIG_ADDRESS
so that it will only receive messages sent to the relevant address
.
The queue
name can be configured with a prefix and suffix.
See the relevant settings in the table below:
address-setting |
default |
---|---|
|
|
|
(empty string) |
Here is an example configuration:
<address-setting match="#">
<expiry-address>expiryAddress</expiry-address>
<auto-create-expiry-resources>true</auto-create-expiry-resources>
<expiry-queue-prefix></expiry-queue-prefix> <!-- override the default -->
<expiry-queue-suffix>.EXP</expiry-queue-suffix>
</address-setting>
The queue holding the expired messages can be accessed directly either by using the queue’s name by itself (e.g. when using the core client) or by using the fully qualified queue name (e.g. when using a JMS client) just like any other queue.
Also, note that the queue is auto-created which means it will be auto-deleted as per the relevant address-settings
.
5. Configuring The Expiry Reaper Thread
A reaper thread will periodically inspect the queues to check if messages have expired.
The reaper thread can be configured with the following properties in broker.xml
- message-expiry-scan-period
-
How often the queues will be scanned to detect expired messages (in milliseconds, default is 30000ms, set to
-1
to disable the reaper thread)
6. Example
See the Message Expiration Example which shows how message expiry is configured and used with JMS.