Developing Robust JMS Applications

The JMS API allows two different ways to achieve various kinds and degrees of reliability. They are,

  1. Using Basic Reliability Mechanism
  2. Using Advanced Reliability Mechanism.

Using Basic Reliability Mechanism.

The below mechanisms are used for extracting the reliable message delivery.

A)    Controlling message acknowledgment:-

It helps to define different levels of control over message acknowledgment. The successful consumption of JMS message happened in three different stages.

  1. The client receives the message.
  2. The client processes the message.
  3. The message is acknowledged. Acknowledgment is initiated either by the JMS provider or by the client, depending on the session acknowledgment mode.

We are using two different methods for handling acknowledgement.

1)      Using transacted session

In this method acknowledgement happens automatically when a transaction is committed and if a transaction id rolled back all consumed messages are delivered.

2)      Using non transacted session

In this method when and how a message is acknowledged depend on the value specified as the second argument of the createSession method. Here we are using three different types of argument values.

1)      Session.AUTO_ACKNOWLEDGE:-

The session automatically acknowledges a client’s receipt of a message either when the client has successfully returned from a call to receive or when the MessageListener it has called to process the message returns successfully. A synchronous receives in an AUTO_ACKNOWLEDGE session is the one exception to the rule that message consumption is a three-stage process as described earlier.

2)      Session.CLIENT_ACKNOWLEDGE:-

A client acknowledges a message by calling the message’s acknowledge method. In this mode, acknowledgment takes place on the session level: Acknowledging a consumed message automatically acknowledges the receipt of all messages that have been consumed by its session. For example, if a message consumer consumes ten messages and then acknowledges the fifth message delivered, all ten messages are acknowledged.

3)      Session.DUPS_OK_ACKNOWLEDGE:-

This option instructs the session to lazily acknowledge the delivery of messages. This is likely to result in the delivery of some duplicate messages if the JMS provider fails, so it should be used only by consumers that can tolerate duplicate messages. (If the JMS provider redelivers a message, it must set the value of the JMS Redelivered message header to true.) This option can reduce session overhead by minimizing the work the session does to prevent duplicates.

B)    Specifying message persistence:-

It helps to define that messages are persistent meaning that they should not lost in the event of a provider failure.

JMS API allows two types of delivery modes for messages to define whether messages are lost if the JMS provider and these delivery modes are the fields of the DeliveryMode interface.

1)       PERSISTENT delivery mode

By default it instructs the JMS provider to take extra care to ensure that a message is not in transit in case of a JMS provider failure. A message sent with this delivery mode is logged to stable storage when it is sent.

2)      NON_PERSISTENT delivery mode

It does not require the JMS provider to store the message or otherwise guarantee that it is not lost if the provider fails.

The delivery modes define in the two ways.

1)      Use setDeliveryMode

Here we are using the MessageProducer interface for implementing this method and it used to set the delivery mode for all messages sent by that producer.

Eg: –

producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);

2)      Use the long form of the send or the publish method

It helps to set the delivery mode for a specific message. The second argument set the delivery mode and the third and fourth arguments set the priority level and expiration time.

Eg: –

producer.send(message, DeliveryMode.NON_PERSISTENT, 3, 10000);

C)    Setting message priority levels:-

We can set the priority levels for messages which can affect the order in which the messages are obsolete. It helps to instruct the JMS provider to deliver urgent message first. Here we are accomplishing this operation in two ways.

1)      Using set priority method

The messageProducer interface used to set the setPriority method and it helps to set the priority level for all messages sent by that producer.

Eg: – The following call sets a priority level of 7 for a producer.

producer.setPriority(7);

2)      Use the long form of the send or the publish method

We can set the priority level for a specific message. The third argument set the priority level. The priority level ranges from 0 to 9 and default priority level is 4.

Eg: –

producer.send (message, DeliveryMode.NON_PERSISTENT, 3, 10000);

D)    Allowing messages to expire:-

It used to specify an expiration time for messages so that they will not be delivered if they are obsolete. By default, a message never expires. If a message will become obsolete after a certain period, however, you may want to set an expiration time. This can be done in two ways.

1)      Using setTimeToLive method

The MessageProducer interface uses this method to set a default expiration time for all messages sent by that producer.

Eg: –

producer.setTimeToLive(60000);

2)      Using the long form of the send or the publish method:-

In this method we set an expiration time for a specific message. The fourth argument helps to set the expiration time in milliseconds.

Eg: –

producer.send (message, DeliveryMode.NON_PERSISTENT, 3, 10000);

E)     Creating temporary destinations:-

It helps to make temporary destinations that last only for the duration of the connection if they are created. For creating JMS destinations (queues and topics) we are using three methods

1)      Using administratively rather than programmatically.

2)      Using JMS API: – The life time of this object are only last for the duration of the connection in which they are created.

3)      Create dynamically by using the Session.createTemporaryQueue and the Session.createTemporaryTopic methods.

Using Advanced Reliability Mechanism

The below mechanisms are user to extracting the reliable message delivery.

1)      Creating durable subscriptions: – This type of subscriptions helps to receive messages published while the subscriber is not active. Durable subscriptions offer the reliability of queues to the publish/subscribe message domain. For creating the durable subscriptions we use the following ways.

A)    Ensure that a pub/sub application receives all published messages, use PERSISTENT delivery mode for the publishers. In addition, use durable subscriptions for the subscribers.The Session.createConsumer method create a nondurable subscriber if a topic is specified as the destination. A nondurable subscriber can receive only messages that are published while it is active.

B)    At the cost of higher overhead, we use the Session.createDurableSubscriber method to create a durable subscriber. A durable subscription can have only one active subscriber at a time.

C)    A durable subscriber registers a durable subscription by defining a unique identity that is retained by the JMS provider. For stabling the durable subscriber by setting the following things.

a)      A client ID for the connection

Set the client ID administratively for a client-specific connection factory using the Admin Console. After using this connection factory to create the connection and the session, you call the createDurableSubscriber method with two arguments: the topic and a string that specifies the name of the subscription:

Eg: –

String subName = "MySub";
MessageConsumer topicSubscriber =
session.createDurableSubscriber(myTopic, subName);

For closing the subscriber we are using the following syntax.

Syntax: –

topicSubscriber.close();

b)      A topic and a subscription name for the subscriber

c)      The JMS provider saves the messages sent or published to the topic, like it would store messages sent to a queue. If the program or another application calls createDurableSubscriber using the same connection factory and its client ID, the same topic, and the same subscription name, the subscription is reactivated, and the JMS provider delivers the messages that were published while the subscriber was inactive. To delete a durable subscription, first close the subscriber, and then use the unsubscribe method, with the subscription name as the argument.

topicSubscriber.close(); 
session.unsubscribe("MySub");

The unsubscribe method deletes the state that the provider maintains for the subscriber

The below figure show the differences between durable and non durable subscriptions.

Non durable subscription

 

Non durable subscription
Non durable subscription

 

Durable subscription

 

 Durable subscription
Durable subscription