[jboss-cvs] JBoss Messaging SVN: r6418 - in trunk/examples/jms/automatic-failover: src/org/jboss/jms/example and 1 other directory.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Tue Apr 14 07:54:47 EDT 2009


Author: timfox
Date: 2009-04-14 07:54:47 -0400 (Tue, 14 Apr 2009)
New Revision: 6418

Modified:
   trunk/examples/jms/automatic-failover/readme.html
   trunk/examples/jms/automatic-failover/src/org/jboss/jms/example/AutomaticFailoverExample.java
Log:
automatic failover example readme

Modified: trunk/examples/jms/automatic-failover/readme.html
===================================================================
--- trunk/examples/jms/automatic-failover/readme.html	2009-04-14 11:23:25 UTC (rev 6417)
+++ trunk/examples/jms/automatic-failover/readme.html	2009-04-14 11:54:47 UTC (rev 6418)
@@ -1,171 +1,159 @@
 <html>
   <head>
-    <title>JBoss Messaging JMS Automatic Failover Example</title>
+    <title>JBoss Messaging JMS Automatic (Transparent) Failover Example</title>
     <link rel="stylesheet" type="text/css" href="../common/common.css">
   </head>
   <body>
-     <h1>JBoss Messaging JMS Automatic Failover Example</h1>
+     <h1>JBoss Messaging JMS Automatic (Transparent) Failover (HA) Example</h1>
      <br>
-     <p>This example demonstrates a JMS queue deployed on two different nodes. The two nodes are configured to form a cluster.</p>
-     <p>We then create a consumer on the queue on each node, and we create a producer on only one of the nodes.</p>
-     <p>We then send some messages via the producer, and we verify that <b>both</b> consumers receive the sent messages
-     in a round-robin fashion.</p>
-     <p>In other words, JBoss Messaging <b>load balances</b> the sent messages across all consumers on the cluster</p>
-     <p>This example uses JNDI to lookup the JMS Queue and ConnectionFactory objects. If you prefer not to use
-     JNDI, these could be instantiated directly.</p>     
-     <p>Here's the relevant snippet from the server configuration, which tells the server to form a cluster between the two nodes
-     and to load balance the messages between the nodes.</p>     
-     <pre>
-     <code>
-   &lt;cluster-connection name="my-cluster"&gt;
-      &lt;address&gt;jms&lt;/address&gt;
-	   &lt;retry-interval&gt;500&lt;/retry-interval&gt;
-	   &lt;use-duplicate-detection&gt;true&lt;/use-duplicate-detection&gt;
-	   &lt;forward-when-no-consumers&gt;true&lt;/forward-when-no-consumers&gt;
-	   &lt;max-hops&gt;1&lt;/max-hops&gt;
-	   &lt;discovery-group-ref discovery-group-name="my-discovery-group"/&gt;
-   &lt;/cluster-connection&gt;
-   </code>
-     </pre>    
-     <p>For more information on JBoss Messaging load balancing, and clustering in general, please see the clustering
+     <p>This example demonstrates two servers coupled as a live-backup pair for high availability (HA), and a client
+     connection transparently failing over from live to backup when the live server is crashed.</p>
+     <p>JBoss Messaging implements seamless, transparent failover of client connections between live and backup servers.
+     This is implemented by the replication of state between live and backup nodes. When replication is configured and a
+     live node crashes, the client connections can carry on as if <i>nothing happened</i> and carry on sending and
+     consuming messages.</p>
+     <p><b>With JBoss Messaging there is no need to code any special client side failover logic in order to benefit from
+     failover and HA. There is no need to refactor your messaging applications to work in an HA environment.</b></p>
+     <p>JBoss Messaging also supports manual failover which is covered in a separate example.</p> 
+     <p>For more information on JBoss Messaging failover and HA, and clustering in general, please see the clustering
      section of the user manual.</p>      
      <h2>Example step-by-step</h2>
      <p><i>To run the example, simply type <code>ant</code> from this directory</i></p>
+     <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>
      <br>
      <ol>
-        <li> Get an initial context for looking up JNDI from server 0.</li>
+        <li> Get an initial context for looking up JNDI from server 1.</li>
         <pre>
-           <code>
-   ic0 = getContext(0);
-   </code>
+           <code>initialContext = getContext(1);</code>
         </pre>
 
-        <li>Look-up the JMS Queue object from JNDI</li>
+        <li>Look-up the JMS Queue object from JNDI on server 1.</li>
         <pre>
-           <code>Queue queue = (Queue)ic0.lookup("/queue/exampleQueue");</code>
+           <code>Queue queue = (Queue)initialContext.lookup("/queue/exampleQueue");</code>
         </pre>
 
-        <li>Look-up a JMS Connection Factory object from JNDI on server 0</li>
+        <li>Look-up a JMS Connection Factory object from JNDI on server 1</li>
         <pre>
-           <code>ConnectionFactory cf0 = (ConnectionFactory)ic0.lookup("/ConnectionFactory");</code>
+           <code>ConnectionFactory connectionFactory = (ConnectionFactory)initialContext.lookup("/ConnectionFactory");</code>
         </pre>
 
-        <li>Get an initial context for looking up JNDI from server 1.</li>
+        <li>We create a JMS Connection</li>
         <pre>
-           <code>ic1 = getContext(1);</code>
+          <code>connection = connectionFactory.createConnection();</code>
         </pre>
-
-        <li>Look-up a JMS Connection Factory object from JNDI on server 1</li>
+        
+        <li>We create a JMS Session</li>
         <pre>
-           <code>ConnectionFactory cf1 = (ConnectionFactory)ic1.lookup("/ConnectionFactory");
-           </code>
+           <code>Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);</code>
         </pre>
-
-        <li>We create a JMS Connection connection0 which is a connection to server 0</li>
-        <pre>
-          <code>
-   connection0 = cf0.createConnection();
-          </code>
-        </pre>
         
-        <li>We create a JMS Connection connection1 which is a connection to server 1</li>
+        <li>We start the connection to ensure delivery occurs on them</li>
         <pre>
-          <code>
-   connection1 = cf1.createConnection();
-          </code>
+           <code>
+   connection.start();
+           </code>
         </pre>
 
-        <li>We create a JMS Session on server 0</li>
+        <li>We create a JMS MessageConsumer</li>
         <pre>
            <code>
-   Session session0 = connection0.createSession(false, Session.AUTO_ACKNOWLEDGE);
+   MessageConsumer consumer = session.createConsumer(queue);
            </code>
         </pre>
-        
-        <li>We create a JMS Session on server 1</li>
+
+        <li>We create a JMS MessageProducer</li>
         <pre>
            <code>
-   Session session1 = connection1.createSession(false, Session.AUTO_ACKNOWLEDGE);
-            </code>
+   MessageProducer producer = session.createProducer(queue);</code>
         </pre>
 
-        <li>We start the connections to ensure delivery occurs on them</li>
+        <li>We send some messages to server 1, the live server. As we do operations on the live server they are
+        transparently replicated to server 0 the backup server, behind the scenes.</li>
         <pre>
            <code>
-   connection0.start();
+	      final int numMessages = 10;
 
-   connection1.start();
+         for (int i = 0; i < numMessages; i++)
+         {
+            TextMessage message = session.createTextMessage("This is text message " + i);
+
+            producer.send(message);
+
+            System.out.println("Sent message: " + message.getText());
+         }
            </code>
         </pre>
-
-        <li>We create JMS MessageConsumer objects on server 0 and server 1</li>
+        
+        <li>We now cause server 1, the live server, to crash, and wait a little while to make sure
+            it has really crashed. When server 1 crashes, the client automatically detects the failure and automatically
+            fails over from server 1 to server 0. (In your real program you wouldn't need to sleep).
+        </li>
+       
         <pre>
            <code>
-   MessageConsumer consumer0 = session0.createConsumer(queue);
-
-   MessageConsumer consumer1 = session1.createConsumer(queue);
+	      killServer(1); // This causes the live server to crash
+         
+         Thread.sleep(2000); // Just wait a little while to make sure the live server has really crashed.
            </code>
-        </pre>
-
-        <li>We create a JMS MessageProducer object on server 0.</li>
+        </pre> 
+        
+        <li>We consume the messages sent before the crash of the live server. We are now transparently
+            reconnected to server 0 - the backup server. Note that all this reconnection has been done
+            without the client being aware it has been reconnected!</li>
         <pre>
            <code>
-   MessageProducer producer = session0.createProducer(queue);</code>
-        </pre>
+         for (int i = 0; i < numMessages; i++)
+         {
+            TextMessage message0 = (TextMessage)consumer.receive(5000);
 
-        <li>We send some messages to server 0.</li>
+            System.out.println("Got message: " + message0.getText());
+         }
+           </code>
+        </pre>
+        
+        <li>We now send some more messages.</li>
         <pre>
            <code>
-	final int numMessages = 10;
+         for (int i = numMessages; i < numMessages * 2; i++)
+         {
+            TextMessage message = session.createTextMessage("This is text message " + i);
 
-	for (int i = 0; i < numMessages; i++)
-	{
-	   TextMessage message = session0.createTextMessage("This is text message " + i);
-	      
-	   producer.send(message);
-	
-	   System.out.println("Sent message: " + message.getText());
-	}
+            producer.send(message);
+
+            System.out.println("Sent message: " + message.getText());
+         }
            </code>
         </pre>
         
-        <li>We now consume those messages on *both* server 0 and server 1.
-         We note the messages have been distributed between servers in a round robin fashion.
-         JBoss Messaging has <b>load balanced</b> the messages between the available consumers on the different nodes.
-         JBoss Messaging can be configured to always load balance messages to all nodes, or to only balance messages
-         to nodes which have consumers with no or matching selectors. See the user manual for more details.</li>
-         JMS Queues implement point-to-point message where each message is only ever consumed by a
-         maximum of one consumer.
+        <li>And consume them.</li>
         <pre>
            <code>
-	for (int i = 0; i < numMessages; i += 2)
-	{
-	   TextMessage message0 = (TextMessage)consumer0.receive(5000);
-	
-	   System.out.println("Got message: " + message0.getText() + " from node 0");
-	
-	   TextMessage message1 = (TextMessage)consumer1.receive(5000);
-	
-	   System.out.println("Got message: " + message1.getText() + " from node 1");
-	}
+         for (int i = 0; i < numMessages; i++)
+         {
+            TextMessage message0 = (TextMessage)consumer.receive(5000);
+
+            System.out.println("Got message: " + message0.getText());
+         }
            </code>
-        </pre> 
+        </pre>
 
-        <li>And finally (no pun intended), <b>always</b> remember to close your JMS 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>
+        <li>And finally (no pun intended), <b>always</b> 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>
            <code>
 	finally
 	{
-	   if (connection0 != null)
-	   {
-	      connection0.close();
-	   }
-	      
-	   if (connection1 != null)
-	   {
-	      connection1.close();
-	   }
+	   if (connection != null)
+      {
+         connection.close();
+      }
+
+      if (initialContext != null)
+      {
+         initialContext.close();
+      }
 	}
            </code>
         </pre>

Modified: trunk/examples/jms/automatic-failover/src/org/jboss/jms/example/AutomaticFailoverExample.java
===================================================================
--- trunk/examples/jms/automatic-failover/src/org/jboss/jms/example/AutomaticFailoverExample.java	2009-04-14 11:23:25 UTC (rev 6417)
+++ trunk/examples/jms/automatic-failover/src/org/jboss/jms/example/AutomaticFailoverExample.java	2009-04-14 11:54:47 UTC (rev 6418)
@@ -60,22 +60,22 @@
          // Step 3. Look-up a JMS Connection Factory object from JNDI on server 1
          ConnectionFactory connectionFactory = (ConnectionFactory)initialContext.lookup("/ConnectionFactory");
 
-         // Step 6. We create a JMS Connection connection0
+         // Step 4. We create a JMS Connection connection
          connection = connectionFactory.createConnection();
 
-         // Step 8. We create a JMS Session
+         // Step 5. We create a JMS Session
          Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
 
-         // Step 10. We start the connections to ensure delivery occurs on them
+         // Step 6. We start the connection to ensure delivery occurs
          connection.start();
 
-         // Step 11. We create a JMS MessageConsumer object
+         // Step 7. We create a JMS MessageConsumer object
          MessageConsumer consumer = session.createConsumer(queue);
 
-         // Step 12. We create a JMS MessageProducer object
+         // Step 8. We create a JMS MessageProducer object
          MessageProducer producer = session.createProducer(queue);
 
-         // Step 13. We send some messages to server 1
+         // Step 9. We send some messages to server 1, the live server
 
          final int numMessages = 10;
 
@@ -88,11 +88,15 @@
             System.out.println("Sent message: " + message.getText());
          }
 
-         // We now cause the server to crash
+         // Step 10. We now cause server 1, the live server to crash, and wait a little while to make sure
+         // it has really crashed
 
          killServer(1);
          
-         // Step 14.
+         Thread.sleep(2000);
+         
+         // Step 11. We consume the messages sent before the crash of the live server. We are now transparently
+         // reconnected to server 0 - the backup server.
 
          for (int i = 0; i < numMessages; i++)
          {
@@ -101,7 +105,7 @@
             System.out.println("Got message: " + message0.getText());
          }
 
-         // Now send some more messages
+         // Step 12. We now send some more messages
 
          for (int i = numMessages; i < numMessages * 2; i++)
          {
@@ -112,6 +116,8 @@
             System.out.println("Sent message: " + message.getText());
          }
 
+         // Step 13. And consume them.
+         
          for (int i = 0; i < numMessages; i++)
          {
             TextMessage message0 = (TextMessage)consumer.receive(5000);
@@ -123,7 +129,7 @@
       }
       finally
       {
-         // Step 15. Be sure to close our resources!
+         // Step 14. Be sure to close our resources!
 
          if (connection != null)
          {




More information about the jboss-cvs-commits mailing list