[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>
- <cluster-connection name="my-cluster">
- <address>jms</address>
- <retry-interval>500</retry-interval>
- <use-duplicate-detection>true</use-duplicate-detection>
- <forward-when-no-consumers>true</forward-when-no-consumers>
- <max-hops>1</max-hops>
- <discovery-group-ref discovery-group-name="my-discovery-group"/>
- </cluster-connection>
- </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