Christian Posta

About Christian Posta

Christian is a Principal Consultant at FuseSource specializing in developing enterprise software applications with an emphasis on software integration and messaging.

Guaranteed messaging for topics, the JMS spec, and ActiveMQ

Recently a customer asked me to look closer at ActiveMQ’s implementation of “persistent” messages, how it applies to topics, and what happens in failover scenarios when there are non-durable subscribers.

I had understood that the JMS semantics specify that only durable subscribers to a topic are guaranteed message delivery for a persistent delivery mode, even in the face of message-broker provider failure. But what does it have to say about non-durable subscribers for persistent messages? What’s the point of sending a message “persistent” when there are no durable subscribers?

Upon looking at the exact wording of the spec, I became a little unsure. So I consulted the Java Message Service book (Richards, Monson-Haefel, and Chappell) for some more discussion around guaranteed messaging, checked into the ActiveMQ source code, and consulted with some of my co-workers.

First, let’s look at what the spec says:

From section 4.10 of the JMS spec:

Most clients should use producers that produce PERSISTENT messages. This insures once-and-only-once message delivery for messages delivered from a queue or a durable subscription.

Pretty clear, right? Using persistent message delivery ensures message delivery for a queue or durable subscription.

From section 6.12:

Unacknowledged messages of a nondurable subscriber should be able to be recovered for the lifetime of that nondurable subscriber.

So now unacked messages of a non-durable subscriber should be able to be recovered? “for the lifetime of that non-durable subscriber” I guess…

But later as part of 6.12:

Only durable subscriptions are reliably able to recover unacknowledged messages.

and…

To ensure delivery, a TopicSubscriber should establish a durable subscription.

Although the spec says very clearly [to the effect] that only queues and durable subscribers can take advantage of the store-and-forward guaranteed delivery, I guess I become confused at the “messages of a non-durable subscriber should be able to be recovered for the lifetime of the non-durable subscriber”

  • Does the persistent protocol change for a topic depending on its consumers (where the message is considered the responsibility of the broker only after the broker has persisted the message and sent the producer an ack)?
  • Does that mean even in the event of broker failure? Or is broker failure considered and end of the life of the subscription for non-durable subs?
  • What happens with ActiveMQ when there is a network of brokers for persistent, non-durable topics? Can messages be missed if a broker in the network fails?
  • What are the exact differences between sending a message “persistent” vs “non-persistent” to a topic with non-durable subscribers?

These are two parts that have to be considered for this discussion of guaranteed delivery. The part where the publisher is sending a message to the broker, and when the consumer is receiving a message from the broker. For persistent messages, the protocol is for the sender to send a message and the broker to ack the message only after it has been persisted to a store. On the other hand, the consumer must ack the message after the broker has delivered it to say “hey, I’ll take responsibility of the message now”. Only then will the broker relinquish responsibility and removing it from its store.  

Does the protocol change for a topic depending on its consumers?

So for persistent messages sent to a topic (not taking into any account consumers at the moment), does the spec say anything about whether the message is supposed to be stored before the broker sends back its ack? No, it doesn’t. It’s left up to the implementors of the JMS broker in question. In the case of ActiveMQ, if there are ONLY non-durable subscriptions on a topic, it will NOT persist the message.

The synchronous nature of the protocol does not change, i.e., if the message is sent persistent, the session will consider the exchange with the broker to be synchronous, and it will wait for a response from the broker before proceeding — but the broker will not actually persist the message. In ActiveMQ, this changes if there is AT LEAST one durable subscriber. Then the broker will persist the message (per the JMS spec).  

Does that mean even in the event of a broker failure?

The lifetime of a non-durable subscription is indeed broken if a broker fails. So a message will not be delivered, even if it’s sent persistent, to a non-durable subscriber in the event of broker failure (or any other termination of the life of that non-durable sub). Additionally, a message will not be redelivered in the face of broker failure for non-durable subscriptions.  

What happens in a network of brokers?

Messages can indeed be lost. Consider this network of brokers where A -> B -> C and subscription is demand forwarded from C -> B -> A. So if we have a producer at A producing to a topic “topic.foo” and a non-durable consumer is on broker C consuming from “topic.foo”, if broker B goes down, messages thereafter sent to A will be dropped. The lifetime of the subscription as far as A knows has been terminated.

Lastly,  

What are the exact differences between sending a message “persistent” vs “non-persistent” to a topic with non-durable subscribers?

According to the JMS spec:

How PublishedNondurable SubscriberDurable Subscriber
NON_PERSISTENTat-most-once (missed if inactive)at-most-once
PERSISTENTonce-and-only-once (missed if inactive)once-and-only-once

So for a non-durable subscriber, a non-persistent message will be delivered “at most once” but will be missed if inactive (or broker failure).

For a non-durable subscriber, a persistent message will be delivered “once and only once” but missed if inactive. The “inactive” part of the spec effectively means if there are no durable subscribers to a topic, a message could be lost and there is no guarantee of delivery regardless of whether the message is sent persistent or non-persistent.

Reference: Guaranteed messaging for topics, the JMS spec, and ActiveMQ from our JCG partner Christian Posta at the Christian Posta Software blog.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

Leave a Reply


1 × = two



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close