in Apache English Activemq Jms ~ read.
X-raying Consumer Acknowledgements in Apache ActiveMQ

X-raying Consumer Acknowledgements in Apache ActiveMQ

The Java Message Service (JMS) specification defines that all messages exchanged between a client and a broker must be acknowledged sooner or later. The acknowledgement serves as a token to signal transfer of responsibility between two parties, they exist in producer => broker and broker => consumer interactions.

When a producer sends a message to a broker/provider, the provider must ACK the receipt after it has honoured the persistence requirement. Likewise, when the broker dispatches a message to a consumer, the consumer must ACK the receipt at the point it decides to assume full responsibility for the processing. Brokers reserve their right to redeliver messages to consumers if they are not ACK'ed in time.

The moment when a message is ACK'ed can greatly affect performance, and whether it's done manually or automatically too. It's easy for ACKs to become a bottleneck.

In this article, I'll shed light on the different ACK modes that exist in Apache ActiveMQ

JMS Acknowledgement modes

First things first, some background information. The JMS specification brings forward four acknowledgement modes of compulsory implementation for all JMS providers:

  • AUTO_ACKNOWLEDGE => the session automatically acknowledges a client’s receipt of a message when it has either successfully returned from a call to receive or the MessageListener it has called to process the message successfully returns (default ACK mode).
  • DUPS_OK_ACKNOWLEDGE => instructs the session to lazily acknowledge the delivery of messages.
  • CLIENT_ACKNOWLEDGE => client acknowledges a message by calling the message's acknowledge method. Acknowledging a consumed message automatically acknowledges the receipt of all messages that have been delivered by its session.
  • SESSION_TRANSACTED => a fictional value returned from Session.getAcknowledgeMode if the session is transacted. Cannot be set explicitly.

These values are defined as constants in the javax.jms.Session

ActiveMQ Enhancements

On top of those, Apache ActiveMQ defines 2 further acknowledgement behaviours:

  • ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE => Special version of the CLIENT_​ACKNOWLEDGE mode which allows to cherry-pick messages to ACK.

    • Message.ack() only acks an individual message, as opposed to acting as a cumulative ack.
  • Optimized Acknowledgements => batches up the transmission of the ACK to the broker until 65% of the prefetch buffer has been processed or until a timeout elapses, whatever happens first.

    • Enable this feature in the client's , optimizeAcknowledgeConnection Factory URI

    • Also configure the timeout period in the , optimizeAcknowledgeTimeOutConnection Factory URI

    • Only makes sense to activate alongside an automatic ACK mode, i.e. AUTO_ACKNOWLEDGE or DUPS_OK_ACKNOWLEDGE.

The rules of the game

Given so many options and descriptions, how does it all work in real life? These are the rules of the game in release 5.6.0 of Apache ActiveMQ:

  • For QUEUES, there is no difference between AUTO_ACKNOWLEDGE and DUPS_OK_ACKNOWLEDGE.

    • Even though the JMS spec allows for lazy acks with DUPS_OK_ACKNOWLEDGE, the AMQ client library doesn't leverage possibility and acks each message one by one in both modes, unless Optimized Acknowledgements are enabled.
  • For TOPICS:

    • DUPS_OK_ACKNOWLEDGE batches up acknowledgements until 50% worth of the prefetch buffer has been processed, at which point one cumulative ack is sent back.

    • Conversely, AUTO_ACKNOWLEDGE acknowledges messages individually.

  • When you enable Optimized Acknowledgements, the enhancement only really comes into play in one of two cases:

    • If AUTO_ACKNOWLEDGE is enabled, regardless if the destination is a queue or a topic.

    • If DUPS_OK_ACKNOWLEDGE is enabled, only if the destination is a queue.In all other cases, the flag is ignored.

  • When Optimized Acknowledgements are in effect, the client will send back cumulative acks at whichever event happens first:

    • 65% of the prefetch buffer has been processed

    • The optimized acknowledgements timeout period has elapsed.

  • The "DUPS_OK_ACKNOWLEDGE with topics" scenario sees no alteration with Optimized Acknowledgements, and the watermark continues to be 50%.

  • With INDIVIDUAL_ACKNOWLEDGE, each message you ACK will be ack'ed to the broker specifically in a cherry-picked manner.

  • Conversely, with CLIENT_ACKNOWLEDGE, whenever you ACK a message the client library sends back a cumulative ACK for that message AND all previously delivered but unack'ed messages, inside one single command.

I hope this post was useful to dissipate much of the fog on how acknowledgements, and as usual, if you have further questions, feel free to comment below or to contact me on Twitter: @raulvk

  • Email
  • Facebook
  • Twitter
  • LinkedIn
  • Tumblr
  • Reddit
  • Google+
  • Pinterest
  • Pocket
comments powered by Disqus