activemq-artemis/examples/features/ha/non-transaction-failover
Martyn Taylor bb2c890803 [maven-release-plugin] prepare for next development iteration 2015-09-15 15:43:44 +01:00
..
src/main renaming broker-features -> features on examples 2015-08-13 00:11:56 -04:00
pom.xml [maven-release-plugin] prepare for next development iteration 2015-09-15 15:43:44 +01:00
readme.html renaming broker-features -> features on examples 2015-08-13 00:11:56 -04:00

readme.html

<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
-->

<html>
  <head>
    <title>ActiveMQ Artemis JMS Failover Without Transactions 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>JMS Failover Without Transactions Example</h1>

     <pre>To run the example, simply type <b>mvn verify</b> from this directory.</pre>


     <p>This example demonstrates two servers coupled as a live-backup pair for high availability (HA), and a client
     connection failing over from live to backup when the live server is crashed.</p>
     <p>Failover behavior differs whether the JMS session is transacted or not.</p>
     <p>When a <em>non-transacted</em> JMS session is used, once and only once delivery is not guaranteed
        and it is possible some messages will be lost or delivered twice, depending when the failover to the backup server occurs.</p>
     <p>It is up to the client to deal with such cases. To ensure once and only once delivery, the client must
        use transacted JMS sessions (as shown in the example for <a href="../transaction-failover/readme.html">failover with transactions</a>).</p>
     <p>For more information on ActiveMQ Artemis failover and HA, and clustering in general, please see the clustering
     section of the user manual.</p>

     <h2>Example step-by-step</h2>
     <p>In this example, the live server is server 1, and the backup server is server 0</p>
     <p>The connection will initially be created to server1, server 1 will crash, and the client will carry on
     seamlessly on server 0, the backup server.</p>
     <ol>
        <li>Get an initial context for looking up JNDI from server #1.</li>
        <pre class="prettyprint">
           initialContext = getContext(1);
        </pre>

        <li>Look up the JMS resources from JNDI on server #1.</li>
        <pre class="prettyprint">
           Queue queue = (Queue)initialContext.lookup("/queue/exampleQueue");
           ConnectionFactory connectionFactory = (ConnectionFactory)initialContext.lookup("/ConnectionFactory");
        </pre>

        <li>Create a JMS Connection</li>
        <pre class="prettyprint">
           connection = connectionFactory.createConnection();
        </pre>

        <li>Create a JMS <em>non-transacted</em> Session with client acknowledgement</li>
        <pre class="prettyprint">
           Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
        </pre>

        <li>Start the connection to ensure delivery occurs</li>
        <pre class="prettyprint">
           connection.start();
        </pre>

        <li>Create a JMS MessageProducer and MessageConsumer</li>
        <pre class="prettyprint">
           MessageProducer producer = session.createProducer(queue);
           MessageConsumer consumer = session.createConsumer(queue);
        </pre>

        <li>Send some messages to server #1</li>
        <pre class="prettyprint">
           for (int i = 0; i &lt; numMessages; i++)
           {
              TextMessage message = session.createTextMessage("This is text message " + i);
              producer.send(message);
              System.out.println("Sent message: " + message.getText());
           }
        </pre>

        <li>Receive and acknowledge half of the sent messages</li>
        <pre class="prettyprint">
           TextMessage message0 = null;
           for (int i = 0; i &lt; numMessages / 2; i++)
           {
              message0 = (TextMessage)consumer.receive(5000);
              System.out.println("Got message: " + message0.getText());
           }
           message0.acknowledge();
        </pre>

        <li>Receive the second half of the sent messages but <em>do not acknowledge them yet</em></li>
        <pre class="prettyprint">
           for (int i = numMessages / 2; i &lt; numMessages; i++)
           {
              message0 = (TextMessage)consumer.receive(5000);
              System.out.println("Got message: " + message0.getText());
           }
        </pre>

        <li>Crash server #1, the live server, and wait a little while to make sure it has really crashed.</li>
        <pre class="prettyprint">
           killServer(1);
           Thread.sleep(2000);
        </pre>

        <li>Acknowledging the second half of the sent messages will fail as failover to the backup server has occurred</li>
        <pre class="prettyprint">
           try
           {
              message0.acknowledge();
           }
           catch (JMSException e)
           {
              System.err.println("Got exception while acknowledging message: " + e.getMessage());
           }
        </pre>

         <li>Consume again the second half of the messages againg. Note that they are not considered as redelivered</li>
        <pre class="prettyprint">
           for (int i = numMessages / 2; i &lt; numMessages; i++)
           {
              message0 = (TextMessage)consumer.receive(5000);
              System.out.printf("Got message: %s (redelivered?: %s)\n", message0.getText(), message0.getJMSRedelivered());
           }
           message0.acknowledge();
        </pre>

        <li>And finally, <strong>always</strong> remember to close your 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">
           finally
           {
              if (connection != null)
              {
                 connection.close();
              }

              if (initialContext != null)
              {
                 initialContext.close();
              }
           }
        </pre>

     </ol>
  </body>
</html>