2014-10-31 06:20:28 -04:00
< html >
< head >
2014-11-19 03:44:57 -05:00
< title > ActiveMQ JMS Load Balanced Clustered Queue Example< / title >
2014-10-31 06:20:28 -04:00
< 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 Load Balanced Clustered Queue Example< / h1 >
< 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 >
2014-11-19 03:44:57 -05:00
< p > In other words, ActiveMQ < b > load balances< / b > the sent messages across all consumers on the cluster< / p >
2014-10-31 06:20:28 -04:00
< 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 class = "prettyprint" >
< code > < cluster-connection name="my-cluster">
< address> jms< /address>
< connector-ref>netty-connector< /connector-ref>
< 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 >
2014-11-19 03:44:57 -05:00
< p > For more information on ActiveMQ load balancing, and clustering in general, please see the clustering
2014-10-31 06:20:28 -04:00
section of the user manual.< / p >
< h2 > Example step-by-step< / h2 >
< p > < i > To run the example, simply type < code > mvn verify< / code > from this directory< / i > < / p >
< ol >
< li > Get an initial context for looking up JNDI from server 0.< / li >
< pre class = "prettyprint" >
< code >
ic0 = getContext(0);
< / code >
< / pre >
< li > Look-up the JMS Queue object from JNDI< / li >
< pre class = "prettyprint" >
< code > Queue queue = (Queue)ic0.lookup("/queue/exampleQueue");< / code >
< / pre >
< li > Look-up a JMS Connection Factory object from JNDI on server 0< / li >
< pre class = "prettyprint" >
< code > ConnectionFactory cf0 = (ConnectionFactory)ic0.lookup("/ConnectionFactory");< / code >
< / pre >
< li > Get an initial context for looking up JNDI from server 1.< / li >
< pre class = "prettyprint" >
< code > ic1 = getContext(1);< / code >
< / pre >
< li > Look-up a JMS Connection Factory object from JNDI on server 1< / li >
< pre class = "prettyprint" >
< code > ConnectionFactory cf1 = (ConnectionFactory)ic1.lookup("/ConnectionFactory");
< / code >
< / pre >
< li > We create a JMS Connection connection0 which is a connection to server 0< / li >
< pre class = "prettyprint" >
< code >
connection0 = cf0.createConnection();
< / code >
< / pre >
< li > We create a JMS Connection connection1 which is a connection to server 1< / li >
< pre class = "prettyprint" >
< code >
connection1 = cf1.createConnection();
< / code >
< / pre >
< li > We create a JMS Session on server 0< / li >
< pre class = "prettyprint" >
< code >
Session session0 = connection0.createSession(false, Session.AUTO_ACKNOWLEDGE);
< / code >
< / pre >
< li > We create a JMS Session on server 1< / li >
< pre class = "prettyprint" >
< code >
Session session1 = connection1.createSession(false, Session.AUTO_ACKNOWLEDGE);
< / code >
< / pre >
< li > We start the connections to ensure delivery occurs on them< / li >
< pre class = "prettyprint" >
< code >
connection0.start();
connection1.start();
< / code >
< / pre >
< li > We create JMS MessageConsumer objects on server 0 and server 1< / li >
< pre class = "prettyprint" >
< code >
MessageConsumer consumer0 = session0.createConsumer(queue);
MessageConsumer consumer1 = session1.createConsumer(queue);
< / code >
< / pre >
< li > We create a JMS MessageProducer object on server 0.< / li >
< pre class = "prettyprint" >
< code >
MessageProducer producer = session0.createProducer(queue);< / code >
< / pre >
< li > We send some messages to server 0.< / li >
< pre class = "prettyprint" >
< code >
final int numMessages = 10;
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());
}
< / 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.
2014-11-19 03:44:57 -05:00
ActiveMQ has < b > load balanced< / b > the messages between the available consumers on the different nodes.
ActiveMQ can be configured to always load balance messages to all nodes, or to only balance messages
2014-10-31 06:20:28 -04:00
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.
< pre class = "prettyprint" >
< 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");
}
< / code >
< / 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 >
< pre class = "prettyprint" >
< code >
finally
{
if (connection0 != null)
{
connection0.close();
}
if (connection1 != null)
{
connection1.close();
}
}
< / code >
< / pre >
< / ol >
< / body >
< / html >