Sun Java logo     Previous      Contents      Index      Next     

Sun logo
Sun Java System Message Queue 3 2005Q1 Technical Overview 

Chapter 3
Reliable Message Delivery

This chapter describes how the Message Queue service provides reliable message delivery. It traces the path of a message through the system, describing the various mechanisms used to route and deliver the message to the appropriate consumer, and to guarantee that it has been delivered.

The chapter covers the following topics:

This chapter has material of interest to both developers and administrators and supplements the information in Chapter 2, "Introduction to Message Queue."


A Message’s Journey Through the System

The delivery of a message by the Message Queue message service, from a message producer to a message consumer is illustrated in Figure 3-1. The subsections that follow provide a more detailed description of each stage in the delivery process.

Figure 3-1  Message Delivery Steps

Diagram showing steps in the message delivery process in case of a persistent, reliably delivered message. Figure is described in text.

Message delivery steps for a persistent, reliably delivered message are as follows:

Message Production

1.   The client runtime delivers the message over the connection from the message producer to the message server.

Message Handling and Routing

2.   The message server reads in the message from the connection and places it in the appropriate destination.

3.   The message server places the (persistent) message in the data store.

4.   The message server acknowledges receipt of the message to the client runtime of the message producer.

5.   The message server determines the routing for the message.

6.   The message server writes out the message from its destination to the appropriate connection.

Message Consumption

7.   The message consumer’s client runtime delivers the message from the connection to the message consumer.

8.   The message consumer’s client runtime acknowledges consumption of the message to the message server.

Message End-of-Life

9.   The message server processes the client acknowledgement, deleting the (persistent) message from both its destination and the data store.

10.   The message server confirms to the consumer’s client runtime that the client acknowledgement has been processed and the message cannot be delivered again.

The messages handled by the system in the course of these delivery steps fall into two categories:


Message Delivery Processing

The processing of a message by a Message Queue service, in the course of its delivery from producer to consumer, proceeds in several stages, as shown in the description of the steps following Figure 3-1.

The stages are as follows:

These stages are described in the following sections.

Message Production

In message production, a message is created by the client and sent by the client runtime over a connection to a destination on a broker.

If the message’s delivery mode has been set to persistent (guaranteed delivery, once and only once, even if the broker fails), the broker, by default, sends a control message—a broker acknowledgement—back to the client runtime. This broker acknowledgement indicates that the broker delivered the message to its destination and stored it in the broker’s data store. The client thread blocks until it receives the broker acknowledgement.

If the message’s delivery mode has been set to non-persistent, the broker, by default, does not send a broker acknowledgement back to the client runtime and the client thread does not block. However, if it is important to know whether the broker receives non-persistent messages, you can enable broker acknowledgement. In fact, broker acknowledgement must be enabled for the broker to slow message production when destination memory limits are reached (see Destination Message Limits).

Message Handling and Routing

When the broker receives an incoming JMS payload message, it places it in its target destination and then routes it to the appropriate consumer or consumers.

In general, all messages remain at their physical destination (in memory) until they are delivered or expire. If the broker should fail, these messages would be lost. If a message is persistent, the broker stores it in a database or file system and recovers it after a failure.

The handling of a message depends on its destination type—queue or topic—as described in the following sections. It also depends on destination properties that are set for the destination when the administrator creates the physical destination.

Queue Destinations

Queue destinations are used in point-to-point messaging, where a message is meant for delivery to and consumption by only one consumer.

While any message in a queue is delivered to only a single consumer, Message Queue allows multiple consumers to register with a queue. The broker can then distribute messages to the different registered consumers, balancing the load among them.

Basic Routing Mechanisms

Messages are queued as they arrive from producers. As each message reaches the front of the queue, it is routed to a single consumer registered with the queue. The order in which a message reaches the front of the queue depends on the order of its arrival and on its priority.

If a selector property value has been set in a message, the broker compares it to any selector values specified by the registered consumer, and ensures that the selector values match before routing the message to the consumer.

Queue Delivery to Multiple Consumers

The implementation of queue delivery to multiple consumers uses a configurable load-balancing approach based on a number of queue destination properties:

New consumers are rejected if the number of consumers exceeds the sum of these two properties. (Message Queue Platform Edition supports up to three consumers per queue—two active and one backup—and Message Queue Enterprise Edition supports an unlimited number.)

The load-balancing mechanism takes into account the message consumption rate of different consumers. Messages in a queue destination are routed to newly available active consumers (in the order in which they registered with the queue) in batches of a configurable size (the queue destination’s consumer flow limit property). Once these messages have been delivered, additional messages arriving in the queue are routed in batches to consumers as consumers become available. A consumer becomes available when it has consumed a configurable percentage of messages previously delivered to it. In other words, the dispatch rate to each consumer depends on the consumer’s current capacity and message processing rate.

If an active consumer fails, then the first backup consumer is made active and takes over the work of the failed consumer. Because of these mechanisms, if a queue destination has more than one active consumer, no guarantee can be made about the order in which messages are consumed.

When the rate of message production is slow, the broker might dispatch messages unevenly among active consumers. If you have more active consumers than necessary, some may never receive messages.

In a broker cluster environment, you can set delivery to multiple consumers to prioritize local consumers. You can use a queue destination property to specify that messages be delivered to remote consumers only if there are no consumers on a producer’s home broker—that is, the broker to which the producer sent its messages (the local broker). This lets you increase performance in situations where routing to remote consumers (through their home brokers) might cause slowdowns in throughput.

Topic Destinations

Topic destinations are used in publish/subscribe messaging, where a message is meant for delivery to all consumers that have registered an interest in the destination.

Basic Routing Mechanisms

As a message arrives from a producer, it is routed to all consumers subscribed to the topic. If consumers have registered a durable subscription to the topic, they do not have to be active when the message arrives to receive the message: the broker will store the message until the consumer is once again active, and then deliver the message.

If a selector property value has been set in a message, the broker compares it to any selector values specified by the registered consumer, and ensures that the selector values match before routing the message to the consumer.

Durable Subscriptions and Client Identifiers

Only one user may have a durable subscription to a topic. As that user opens and closes connections to the message server, the user’s identity must remain the same. A client identifier is used to make sure that each durable subscription corresponds to only one user.

A client identifier associates a client’s connection to a message server with state information maintained by the message server on behalf of the client. By definition, a client identifier is unique.

To create a durable subscription, a client identifier must be either programmatically set by the client, using a JMS API method call, or administratively configured in the connection factory objects used by the client.

Message Consumption

Once messages have been routed, they are delivered to their respective consumers. When a consumer receives a payload message, the consuming client runtime sends the broker an acknowledgement that the message has been received and processed by the client. The broker waits for this client acknowledgement before deleting the message from its destination. Client acknowledgements can apply to individual messages, groups of messages, or transactions.

Client Acknowledgements

In accordance with the JMS specification, a client can specify one of three basic acknowledgement modes when creating a session. Which mode you choose depends on the message delivery reliability desired:

Message Queue extends the set of client acknowledgement modes with the addition of a NO_ACKNOWLDEGE mode. The basic and extended modes are described in the following subsections.

AUTO_ACKNOWLEDGE Mode

In the AUTO_ACKNOWLEDGE mode, the session automatically acknowledges each message consumed by the client. In addition, the session thread blocks, waiting for the broker to confirm that it has processed the client acknowledgement for each consumed message. This confirmation, in turn, is called a broker acknowledgement.

CLIENT_ACKNOWLEDGE Mode

CLIENT_ACKNOWLEDGE mode gives the client the most control. In this mode, the client explicitly acknowledges after one or more messages have been consumed. The acknowledgement takes place when the client calls the acknowledge() method of a message object, causing the session to acknowledge all messages that have been consumed by the session since the previous invocation of the method. (This could include messages consumed asynchronously by many different message listeners in the session, independent of the order in which they were consumed.)

In addition, the session thread blocks, waiting for the return broker acknowledgement for the batch of consumed messages, which confirms that the broker has processed the client acknowledgement.

Because client acknowledgements and broker acknowledgements are generally batched (rather than being sent one by one), CLIENT_ACKNOWLEDGE mode generally conserves connection bandwidth and reduces the overhead for broker acknowledgements, as compared with AUTO_ACKNOWLEDGE mode. Of course, if in this mode, the client acknowledges each message, no batching will occur, and the acknowledgements are sent one by one.


Note

Message Queue also provides a specific method you can use in CLIENT_ACKNOWLEDGE mode, by which you can acknowledge only the individual message on which you invoke the method, rather than the standard behavior. This is achieved using programming techniques described in the Message Queue Developer’s Guide for Java Clients.


DUPS_OK_ACKNOWLEDGE Mode

In DUPS_OK_ACKNOWLEDGE mode, the session acknowledges after ten messages have been consumed. This value is not currently configurable. Unlike AUTO_ACKNOWLEDGE or CLIENT_ACKNOWLEDGE modes, the session thread does not block waiting for a broker acknowledgement, because no broker acknowledgement is requested in the DUPS_OK_ACKNOWLEDGE mode.

This means there is no guarantee that messages are delivered and consumed only once. In general, messages will not be redelivered very often; they are redelivered only in cases of failure, where the broker has not received a client acknowledgement for a message it has delivered. Clients should use DUPS_OK_ACKNOWLEDGE mode if they don’t care about duplicate delivery.

Because client acknowledgements are batched and the client thread does not block, message throughput is generally much higher than in other modes.

NO_ACKNOWLEDGE Mode

In NO_ACKNOWLEDGE mode, the broker performs the client acknowledgement on behalf of the client, so there is no guarantee that a message has been successfully processed by the consuming client.

Use this mode when message throughput is important but reliable delivery is not. This might be the case, for example, when messages are sent periodically at short intervals, so message load is high and lost messages do not matter a lot.

This mode extends the JMS specification and should only be used by clients that do not need to work with other JMS providers.

Transactions

The client and broker acknowledgement processes described above apply, as well, to JMS message deliveries grouped into transactions. In such cases, client and broker acknowledgements operate on the level of the transaction, including all messages involved in the transaction. When a transaction commits, a broker acknowledgement is sent automatically.

The broker tracks transactions, allowing them to be committed or rolled back should they fail. This transaction management also supports local transactions that are part of larger, distributed transactions (see Distributed Transactions). The broker tracks the state of these transactions until they are committed. When a broker starts up, it inspects all uncommitted transactions and, by default, rolls back all transactions except those in a PREPARED state, which must be resolved manually.

Message Queue implements support for distributed transactions through an XA connection factory, which lets you create XA connections, which in turn let you create XA sessions. In addition, support for distributed transactions requires either a third party Java Transaction Service (JTS) or a J2EE-compliant Application Server (that provides JTS).

Message-End-of-Life

The broker deletes messages from destination memory after they are successfully delivered. However, there are times when a message might be discarded without having been successfully delivered. The following subsections describe the conditions under which messages are discarded.

Normal Deletion of Messages

Under normal conditions, the broker deletes a message from destination memory when the message has been successfully delivered, as confirmed by a client acknowledgement.

When a broker delivers a message to a consumer, it marks the message as delivered, but does not really know whether it has been received and consumed. Therefore, the broker waits for a client acknowledgment before deleting the message from its physical destination and from persistent store.

If the message is sent to a topic, the broker does not delete it until it has received a client acknowledgement from each message consumer to which it has delivered the message. In the case of durable subscriptions to a topic, the broker retains each message in that destination, delivering it as each durable subscriber becomes an active consumer. The broker records client acknowledgements as it receives them and deletes the message only after all the acknowledgements have been received (unless the message expires before then). Depending on the client acknowledgement mode, the broker may confirm receipt of the client acknowledgement by sending a broker acknowledgement back to the client.

If a broker or the connection were to fail, the broker might not receive a client acknowledgement and will redeliver all previously delivered but unacknowledged messages, marking them with a Redelivered flag. For example, if a queue consumer goes off line before acknowledging receipt of a message, and another consumer (or even the same consumer) subsequently registers with the queue, the broker will redeliver the unacknowledged message to the new consumer, marking it with a Redelivered flag. Client applications concerned about redelivery of a message under such conditions should check messages for the this flag.


Note

There is a JMS API (recover Session) by which a client can explicitly request redelivery of messages that have been received but not yet acknowledged by the client. When redelivering such messages, the broker marks them with a Redelivered flag.


Abnormal Deletion of Messages

When a message cannot be delivered, it is either discarded or placed on the dead message queue, depending on the conditions that prevented its delivery.

A message would be discarded by the broker before having been successfully delivered and consumed under the following conditions:

However, under these conditions, a message would be considered dead and either discarded or placed on the dead message queue, depending on the behavior you configure:

You can choose to retain such messages and have them placed in a dead message queue. When placing messages in the dead message queue, the broker writes Message Queue-specific property values to the message, specifying the time and reason for placing them there.

You can subsequently retrieve messages from the dead message queue for diagnostic purposes. See The Dead Message Queue. for more information.


Performance Issues

The more reliable the delivery of messages, the more overhead and bandwidth are required to achieve it. The trade-off between reliability and performance is therefore a significant design consideration. You can maximize performance by choosing to produce and consume non-persistent messages. On the other hand, you can maximize reliability by producing and consuming persistent messages and using transacted sessions. Between these extremes are a number of options, depending on the needs of each application.

The rate at which messages can be processed, for example, is a product of many factors, including messaging application design, configuration of the message server, and configuration of the client runtime. Although these factors are quite distinct, their interactions can complicate the task of maximizing performance.

This section briefly reviews a few of the factors that figure into the trade-off between reliability and performance.

Delivery Mode     The delivery mode specifies whether a message is to be delivered at most once (non-persistent) or once and only once (persistent). The management of persistent messages requires the use of broker acknowledgement messages flowing across a connection and the use of client acknowledgement modes that block, waiting to receive the broker acknowledgements. To increase throughput, you can set the client runtime to suppress broker acknowledgements, but this eliminates the guarantee that persistent messages are delivered once and only once.

Client Acknowledgement Mode     Each of the four client acknowledgement modes requires a different level of processing and bandwidth overhead. AUTO_ACKNOWLEDGE mode consumes the most overhead and guarantees reliability on a message-by-message basis, CLIENT_ACKNOWLEDGE mode batches acknowledgements and therefore requires less bandwidth overhead, while DUPS_OK_ACKNOWLEDGE mode consumes the least overhead but allows for duplicate delivery of messages. NO_ACKNOWLEDGE mode gives the best performance at the cost of possible message loss.

Client Application Design     The number of messages queued up in a session is a function of the number of message consumers using the session and the message load for each consumer. If a client is slow in producing or consuming messages, you can normally improve performance by redesigning the application to distribute message producers and consumers among a greater number of sessions or to distribute sessions among a greater number of connections. Design issues that affect performance are discussed in the Message Queue Developer’s Guide for Java Clients and the Message Queue Developer’s Guide for C Clients.

Message Flow Metering     The contention between control messages and payload messages for connection bandwidth can be managed by the client runtime. Configuring the client runtime appropriately can help speed the delivery of broker acknowledgements, freeing blocked session threads and speeding up consumption of messages. See the Message Queue Administration Guide for more information.

Message Flow Limits     Message consumption can be slowed when client runtime resource limitations are approached. By limiting the number of messages held in the client runtime waiting to be consumed by one or more consumers, these resource limitations can be avoided. See the Message Queue Administration Guide for more information.



Previous      Contents      Index      Next     


Part No: 819-0069-10.   Copyright 2005 Sun Microsystems, Inc. All rights reserved.