mirror of
https://github.com/apache/activemq-artemis.git
synced 2025-02-08 02:59:14 +00:00
<html> <head> <title>ActiveMQ Delayed Redelivery Example</title> <link rel="stylesheet" type="text/css" href="../common/common.css" /> <link rel="stylesheet" type="text/css" href="../common/prettify.css" /> <script type="text/javascript" src="../common/prettify.js"></script> </head> <body onload="prettyPrint()"> <h1>Delayed Redelivery Example</h1> <p>This example demonstrates how ActiveMQ can be configured to provide a delayed redelivery in the case where a message needs to be redelivered.</p> <p>Delaying redelivery can often be useful in the case that clients regularly fail or roll-back. Without a delayed redelivery, the system can get into a "thrashing" state, with delivery being attempted, the client rolling back, and delivery being re-attempted ad infinitum in quick succession, using up valuable CPU and network resources.</p> <p>Re-delivery occurs when the session is closed with unacknowledged messages. The unacknowledged messages will be redelivered.</p> <p>By providing a redelivery delay, it can be specified that a delay of, say, 10 seconds is implemented between rollback and redelivery. The specific delay is configurable on both a global and per destination level, by using wild-card matching on the address settings.</p> <h2>Example setup</h2> <p>Redelivery delay is specified in the configuration file <a href="src/main/resources/activemq/server0/activemq-configuration.xml">activemq-configuration.xml</a>:</p> <p>In this example we set the redelivery delay to 5 seconds for the specific example queue. We could set redelivery delay on on multiple queues by specifying a wild-card in the match, e.g. <code>match="jms.#"</code> would apply the settings to all JMS queues and topics.</p> <p>We then consume a message in a transacted session, and rollback, and note that the message is not redelivered until after 5 seconds.</p> <pre class="prettyprint"> <code><address-setting match="jms.queue.exampleQueue"> <redelivery-delay>5000</redelivery-delay> </address-setting> </code> </pre> <p><i>To run the example, simply type <code>mvn verify</code> from this directory</i></p> <ol> <li>Create an initial context to perform the JNDI lookup.</li> <pre class="prettyprint"> <code>initialContext = getContext(0);</code> </pre> <li>Perform a lookup on the queue</li> <pre class="prettyprint"> <code>Queue queue = (Queue)initialContext.lookup("/queue/exampleQueue");</code> </pre> <li>Perform a lookup on the Connection Factory</li> <pre class="prettyprint"> <code>ConnectionFactory cf = (ConnectionFactory)initialContext.lookup("/ConnectionFactory");</code> </pre> <li>Create a JMS Connection</li> <pre class="prettyprint"> <code>connection = cf.createConnection();</code> </pre> <li>Create a transacted JMS Session <pre class="prettyprint"> <code>Session session = connection.createSession(true, 0);</code> </pre> <li>Create a JMS Message Producer</li> <pre class="prettyprint"> <code>MessageProducer producer = session.createProducer(queue);</code> </pre> <li>Create a Text Message</li> <pre class="prettyprint"> <code>TextMessage message = session.createTextMessage("this is a text message");</code> </pre> <li>Send the Message</li> <pre class="prettyprint"> <code>producer.send(message);</code> </pre> <li>We commit the session to effectively send the message to the queue</li> <pre class="prettyprint"> <code>session.commit();</code> </pre> <li>We create a JMS message consumer on the queue</li> <pre class="prettyprint"> <code>MessageConsumer messageConsumer = session.createConsumer(queue);</code> </pre> <li>We start the connection. In order for delivery to occur on any consumers or subscribers on a connection, the connection must be started</li> <pre class="prettyprint"> <code>connection.start();</code> </pre> <li>We receive the message...</li> <pre class="prettyprint"> <code>TextMessage messageReceived = (TextMessage)messageConsumer.receive(5000); System.out.println("1st delivery from " + queue.getQueueName() + ": " + messageReceived.getText());</code> </pre> <li>...but we roll back the session. the message returns to the queue, but only after a 5 second delay</li> <pre class="prettyprint"> <code>session.rollback();</code> </pre> <li>We try to receive the message but it's being delayed</li> <pre class="prettyprint"> <code> messageReceived = (TextMessage)messageConsumer.receive(3000); if (messageReceived != null) { return false; } System.out.println("Redelivery has been delayed so received message is " + messageReceived); </code> </pre> <li>We try and receive the message again, this time we should get it</li> <pre class="prettyprint"> <code> messageReceived = (TextMessage)messageConsumer.receive(3000); System.out.println("2nd delivery from " + queue.getQueueName() + ": " + messageReceived.getText()); </code> </pre> <li>We rollback the session again to cause another redelivery, and we time how long this one takes</code> <pre class="prettyprint"> <code> long start = System.currentTimeMillis(); session.rollback(); messageReceived = (TextMessage)messageConsumer.receive(8000); long end = System.currentTimeMillis(); System.out.println("3nd delivery from " + queue.getQueueName() + ": " + messageReceived.getText() + " after " + (end - start) + " milliseconds."); </code> </pre> <li>And finally, <b>always</b> remember to close your JMS connections and resources after use, in a <code>finally</code> block. Closing a JMS connection will automatically close all of its sessions, consumers, producer and browser objects</li> <pre class="prettyprint"> <code>finally { if (initialContext != null) { initialContext.close(); } if (connection != null) { connection.close(); } }</code> </pre> </ol> <h2>More information</h2> <ul> <li>User Manual's <a href="../../../docs/user-manual/en/html_single/index.html#undelivered-messages">Undelivered Messages chapter</a></li> </ul> </body> </html>