JBoss.orgCommunity Documentation

Chapter 21. Message Redelivery and Undelivered Messages

21.1. Delayed Redelivery
21.1.1. Configuring Delayed Redelivery
21.1.2. Example
21.2. Dead Letter Addresses
21.2.1. Configuring Dead Letter Addresses
21.2.2. Dead Letter Properties
21.2.3. Example
21.3. Delivery Count Persistence

Messages can be delivered unsuccessfully (e.g. if the transacted session used to consume them is rolled back). Such a message goes back to its queue ready to be redelivered. However, this means it is possible for a message to be delivered again and again without any success and remain in the queue, clogging the system.

There are 2 ways to deal with these undelivered messages:

Both options can be combined for maximum flexibility.

Delaying redelivery can often be useful in the case that clients regularly fail or rollback. Without a delayed redelivery, the system can get into a "thrashing" state, with delivery being attempted, the client rolling back, and delivery being re-attempted ad infinitum in quick succession, consuming valuable CPU and network resources.

See Section 11.1.16, “Delayed Redelivery” for an example which shows how delayed redelivery is configured and used with JMS.

To prevent a client infinitely receiving the same undelivered message (regardless of what is causing the unsuccessful deliveries), messaging systems define dead letter addresses: after a specified unsuccessful delivery attempts, the message is removed from the queue and send instead to a dead letter address.

Any such messages can then be diverted to queue(s) where they can later be perused by the system administrator for action to be taken.

HornetQ's addresses can be assigned a dead letter address. Once the messages have be unsuccessfully delivered for a given number of attempts, they are removed from the queue and sent to the dead letter address. These dead letter messages can later be consumed for further inspection.

See Section 11.1.15, “Dead Letter” for an example which shows how dead letter is configured and used with JMS.

In normal use, HornetQ does not update delivery count persistently until a message is rolled back (i.e. the delivery count is not updated before the message is delivered to the consumer). In most messaging use cases, the messages are consumed, acknowledged and forgotten as soon as they are consumed. In these cases, updating the delivery count persistently before delivering the message would add an extra persistent step for each message delivered, implying a significant performance penalty.

However, if the delivery count is not updated persistently before the message delivery happens, in the event of a server crash, messages might have been delivered but that will not have been reflected in the delivery count. During the recovery phase, the server will not have knowledge of that and will deliver the message with redelivered set to false while it should be true.

As this behavior breaks strict JMS semantics, HornetQ allows to persist delivery count before message delivery but disabled it by default for performance implications.

To enable it, set persist-delivery-count-before-delivery to true in hornetq-configuration.xml:

<persist-delivery-count-before-delivery>true</persist-delivery-count-before-delivery>