This is a continuation to my earlier article – Java Message Service(JMS) Explained. Here we will discuss how to tune the message in the producer and consumer.
Let’s take the session creation statement in message producer.
Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
We can send messages in a batch by making the first argument TRUE. In this case we need to explicitly commit after sending the message. Before committing if any exception is thrown, then JMS will roll-back all the messages. Second argument is not valid in message producer, it can be 0.
By default all messages send on activemq are persistent. That means if a consumer is not available to pick up the message, then the message will remain in the queue indefinitely. We can set a message non-persistent by setting the delivery mode in the producer.
Also we can set the priority for a message, but there is no guarantee that the message will be received at the consumer based on that priority. Another property is time to live. By setting this property we can tell the queue to destroy the message while the time to live is expired. In this case also there is no guarantee that queue will remove the message as soon as the time is expired.
Now let’s look at session creation in message consumer.
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
We can pass three different parameters into the session creation method.
Once the message is received, JMS automatically acknowledge the messages if we enable SESSION.AUTO_ACKNOWLEDGE and the message will be removed from the queue.
In case of Session.CLIENT_ACKNOWLEDGE, we need to manually acknowledge the messages.
This is applicable only in the case of explicitly receiving the message using consumer.receive() method, not in the case of listener.
Session.DUPS_OK automatically acknowledge the message. Doesn't have to acknowledge immediately, even though the processing of that message is completed. Improve performance, JMS can batch several messages and acknowledge all together. There is a risk, that if server restart, all the messages that are not acknowledged will be send again.
Instead of false , if we use true then all the messages will be received in a transaction and need to commit(Session.commit()). This is applicable only in the case of consumer.receive() method , not in the case of listener.
Explicitly receive message without using message listener.
connection.start(); Message message = consumer.receive();
Using receive() method we can explicitly grab message from the queue. In this case the consumer will wait for a message indefinitely. Also we can pass the time for which the consumer must wait for the message from queue. See code snippet below.
connection.start(); Message message = consumer.receive(2000);
In this case consumer will wait for 2 sec to get the message from message broker(Queue). If no message is available, it will return null. Need to provide minimum half a second delay.
These are some of the ways to tune the JMS messages in producer and consumer.