Chapter 3. Consumer Performance
3.1. Acknowledgment Modes
Overview
The choice of acknowledgement mode in a consumer has a large impact on performance, because each acknowledgment message incurs the overhead of a message send over the network. The key to improving performance in this area is to send acknowledgments in batches, rather than acknowledging each message individually.
Supported acknowledgment modes
Red Hat JBoss A-MQ supports the following acknowledgment modes:
Session.AUTO_ACKNOWLEDGE
- (Default) In this mode, the JMS session automatically acknowledges messages as soon as they are received. In particular, the JMS session acknowledges messages before dispatching them to the application layer. For example, if the consumer application calls
MessageConsumer.receive()
, the message has already been acknowledged before the call returns. Session.CLIENT_ACKNOWLEDGE
- In this mode, the client application code explicitly calls the
Message.acknowledge()
method to acknowledge the message. In Apache Camel, this acknowledges not just the message on which it is invoked, but also any other messages in the consumer that have already been completely processed. Session.DUPS_OK_ACKNOWLEDGE
- In this mode, the JMS session automatically acknowledges messages, but does so in a lazy manner. If JMS fails while this mode is used, some messages that were completely processed could remain unacknowledged. When JMS is restarted, these messages will be re-sent (duplicate messages).This is one of the fastest acknowledgment modes, but the consumer must be able to cope with possible duplicate messages (for example, by detecting and discarding duplicates).
Session.SESSION_TRANSACTED
- When using transactions, the session implicitly works in
SESSION_TRANSACTED
mode. The response to the transaction commit is then equivalent to message acknowledgment.When JMS transactions are used to group multiple messages, transaction mode is very efficient. But avoid using a transaction to send a single message, because this incurs the extra overhead of committing or rolling back the transaction. ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE
- This non-standard mode is similar to
CLIENT_ACKNOWLEDGE
, except that it acknowledges only the message on which it is invoked. It does not flush acknowledgments for any other completed messages.
optimizeAcknowledge option
The
optimizeAcknowledge
option is exposed on the ActiveMQConnectionFactory
class and must be used in conjunction with the Session.AUTO_ACKNOWLEDGE
mode. When set to true
, the consumer acknowledges receipt of messages in batches, where the batch size is set to 65% of the prefetch limit. Alternatively, if message consumption is slow, the batch acknowledgment will be sent after 300ms. Default is false
.
You can set this option on a consumer URI, as follows:
tcp://hostA:61617?jms.optimizeAcknowledge=true
Choosing the acknowledgment mode
In general, you can achieve the best performance either using JMS transactions, and grouping several messages into a single transaction, or by selecting the
DUPS_OK_ACKNOWLEDGE
mode, which requires you to implement duplicate detection code in your consumer.
A typical strategy for implementing duplicate detection is to insert a unique message ID in a JMS header on the producer side and then to store the received IDs on the consumer side. If you are using Red Hat JBoss A-MQ in combination with Apache Camel, you can easily use the Idempotent Consumer pattern to implement duplicate detection.