3.4. Reliability

Overview

A reliable messaging system guarantees that messages are delivered to their intended recipients in the correct order. JMS guaranteed messaging relies on three mechanisms:
  • message autonomy
  • store and forward delivery for persistent messages
  • message acknowledgments
Red Hat JBoss A-MQ provides additional features for ensuring reliable messaging, including the recovery of failed messages.

Message redelivery

JBoss A-MQ's redelivery policy provides a mechanism for modifying the maximum number of times and the frequency at which the broker attempts to redeliver expired and undeliverable messages.
Normally, the broker tries to redeliver messages to consumers when:
  • Using a transacted session, the producer calls rollback() on the session, or closes before calling commit().
  • With CLIENT_ACKNOWLEDGE specified on a transacted session, the producer calls recover() on the session.
  • The consumer rejects delivery of a message (as when a message is incorrectly formatted).
You can tune the client's redelivery policy by editing its connection in the broker's configuration file.
For details, see ActiveMQ in Action (Snyder, Bosanac, and Davies).

Dead letter queue

When a message cannot be delivered to its destination, JBoss A-MQ sends it to the dead letter queue, ActiveMQ.DLQ. When a message is sent to the dead letter queue, an advisory message is sent to the topic ActiveMQ.Advisory.MessageDLQd.*.
Messages held in the dead letter queue can be consumed or reviewed by an administrator at a later time. This can help with debugging delivery issues and ensures that messages are not lost.
For details, see ActiveMQ in Action (Snyder, Bosanac, and Davies).

Durable subscribers

If a subscriber's connection to a topic fails it will typically miss messages that arrive before it can reconnect. To prevent this from happening subscribers can register a durable subscription. A durable subscription instructs the broker to store all messages arriving at the topic while the durable subscriber is disconnected from it. The broker delivers all accumulated messages that have not expired to the durable subscriber when it reconnects to the topic. If the durable subscriber unsubscribes from the topic without first reconnecting, the broker discards all of the subscriber's accumulated messages.
As with nondurable subscriptions, each durable subscriber gets a copy of the messages sent to the topic. For durable messages, the broker saves only one copy of a message in its durable message store. For each durable subscriber, a durable subscription object in the broker's message store maintains a pointer to its next stored message and dispatches a copy of the message to its subscriber.
For details, see ActiveMQ in Action (Snyder, Bosanac, and Davies).

Exclusive consumers

Messages are consumed off of a queue in FIFO order. If multiple consumers are connected to the queue, there is no way to ensure that any one consumer will receive a particular message or sequence of messages. Using an exclusive consumer, you can direct the broker to select one of a queue's consumers to receive all messages from the queue. If that consumer stops or fails, the broker selects another of the queue's consumers to take its place.
Exclusive consumers can also be used as a distributed locking mechanism. Because messaging is often used to broadcast data from an external resource, you'd probably build redundancy into the system to ensure that the broadcast application continues functioning should individual processes fail. Distributed locks on resources are typically used to limit access of the resource's data to only one process at a time, but they incur overhead and don't work for processes running across multiple machines. In this case, you can employ exclusive consumer functionality to create distributed locks for all processes that access the external resource.
For details, see ActiveMQ in Action (Snyder, Bosanac, and Davies).

Message groups

This feature enables multiple consumers on the same queue to process, in FIFO order, messages tagged with the same JMSXGroupID. It also facilitates concurrency as multiple consumers can parallel process different message groups, each identified by a unique JMSXGroupID.
The producer assigns a message to a group by setting the JMSXGroupID property in the message header. The broker dispatches all messages tagged with the same JMSXGroupID value to a single consumer. If that consumer becomes unavailable, the broker dispatches subsequent messages in the group to another consumer.
Message groups are similar to message selectors, except that the broker selects which consumer receives a particular message group and automatically reassigns the message group to another consumer when the current one becomes unavailable.
For details, see ActiveMQ in Action (Snyder, Bosanac, and Davies).

Retroactive consumers

This feature provides a caching mechanism that improves reliability without the overhead of persistent messaging. It enables consumers to retrieve nonpersistent messages that were sent before the consumer started or that went undelivered because the consumer had to restart.
The broker can cache a configurable number of nonpersistent messages for topic destinations. Enabling this feature requires two steps:
  • Identifying the consumer as retroactive; for example:
    Topic topic=session.createTopic("foo.bar.topicA?consumer.retroactive=true");
  • Setting the cache size for the topic destination in the broker's <destinationPolicy>
For details, see ActiveMQ in Action (Snyder, Bosanac, and Davies).