169 lines
7.0 KiB
HTML
169 lines
7.0 KiB
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 JMS Client-Side Load-Balancing 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 Client-Side Load-Balancing Example</h1>
|
|
|
|
<p>This example demonstrates how connnections created from a single JMS Connection factory can be created
|
|
to different nodes of the cluster. In other words it demonstrates how ActiveMQ does <b>client side load balancing</b> of
|
|
connections across the cluster.</p>
|
|
<p>The particular load-balancing policy can be chosen to be random, round-robin or user-defined. Please see the user
|
|
guide for more details of how to configure the specific load-balancing policy. In this example we will use
|
|
the default round-robin load balancing policy.</p>
|
|
<p>The list of servers over which ActiveMQ will round-robin the connections can either be specified explicitly
|
|
in the connection factory when instantiating it directly, when configuring it on the server or configured
|
|
to use UDP discovery to discover the list of servers over which to round-robin. This example will use UDP
|
|
discovery to obtain the list.</p>
|
|
<p>This example starts three servers which all broadcast their location using UDP discovery. The UDP broadcast configuration
|
|
can be seen in the <code>broker.xml</code> file.</p>
|
|
<p>A JMS ConnectionFactory is deployed on each server specifying the discovery group that will be used by that
|
|
connection factory.</p>
|
|
<p>For more information on ActiveMQ load balancing, 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>mvn verify -Pexample</code> from this directory</i></p>
|
|
|
|
<ol>
|
|
<li> Get an initial context for looking up JNDI from server 0.</li>
|
|
<pre class="prettyprint">
|
|
<code>initialContext = getContext(0);</code>
|
|
</pre>
|
|
|
|
<li>Look-up the JMS Queue object from JNDI</li>
|
|
<pre class="prettyprint">
|
|
<code>Queue queue = (Queue)initialContext.lookup("/queue/exampleQueue");</code>
|
|
</pre>
|
|
|
|
<li>Look-up a JMS Connection Factory object from JNDI on server 0</li>
|
|
<pre class="prettyprint">
|
|
<code>ConnectionFactory connectionFactory = (ConnectionFactory)initialContext.lookup("/ConnectionFactory");</code>
|
|
</pre>
|
|
|
|
<li> We create 3 JMS connections from the same connection factory. Since we are using round-robin
|
|
load-balancing this should result in each sessions being connected to a different node of the cluster</li>
|
|
<pre class="prettyprint">
|
|
<code>
|
|
Connection conn = connectionFactory.createConnection();
|
|
connectionA = connectionFactory.createConnection();
|
|
connectionB = connectionFactory.createConnection();
|
|
connectionC = connectionFactory.createConnection();
|
|
conn.close();
|
|
</code>
|
|
</pre>
|
|
|
|
<li>We create JMS Sessions</li>
|
|
<pre class="prettyprint">
|
|
<code>
|
|
Session sessionA = connectionA.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
|
Session sessionB = connectionB.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
|
Session sessionC = connectionC.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
|
</code>
|
|
</pre>
|
|
|
|
<li>We create JMS MessageProducer objects on the sessions</li>
|
|
<pre class="prettyprint">
|
|
<code>
|
|
MessageProducer producerA = sessionA.createProducer(queue);
|
|
MessageProducer producerB = sessionB.createProducer(queue);
|
|
MessageProducer producerC = sessionC.createProducer(queue);
|
|
</code>
|
|
</pre>
|
|
|
|
<li>We send some messages on each producer</li>
|
|
<pre class="prettyprint">
|
|
<code>
|
|
final int numMessages = 10;
|
|
|
|
for (int i = 0; i < numMessages; i++)
|
|
{
|
|
TextMessage messageA = sessionA.createTextMessage("A:This is text message " + i);
|
|
producerA.send(messageA);
|
|
System.out.println("Sent message: " + messageA.getText());
|
|
|
|
TextMessage messageB = sessionB.createTextMessage("B:This is text message " + i);
|
|
producerB.send(messageB);
|
|
System.out.println("Sent message: " + messageB.getText());
|
|
|
|
TextMessage messageC = sessionC.createTextMessage("C:This is text message " + i);
|
|
producerC.send(messageC);
|
|
System.out.println("Sent message: " + messageC.getText());
|
|
}
|
|
</code>
|
|
</pre>
|
|
|
|
<li>We start the connection to consume messages</li>
|
|
<pre class="prettyprint">
|
|
<code>
|
|
connectionA.start();
|
|
connectionB.start();
|
|
connectionC.start();
|
|
</code>
|
|
</pre>
|
|
|
|
<li>We consume messages from the 3 session, one at a time.<br>
|
|
We try to consume one more message than expected from each session. If
|
|
the session were not properly load-balanced, we would be missing a
|
|
message from one of the sessions at the end.</li>
|
|
<pre class="prettyprint">
|
|
<code>
|
|
consume(sessionA, queue, numMessages, "A");
|
|
consume(sessionB, queue, numMessages, "B");
|
|
consume(sessionC, queue, numMessages, "C");
|
|
</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 (connectionA != null)
|
|
{
|
|
connectionA.close();
|
|
}
|
|
if (connectionB != null)
|
|
{
|
|
connectionB.close();
|
|
}
|
|
if (connectionC != null)
|
|
{
|
|
connectionC.close();
|
|
}
|
|
|
|
if (initialContext != null)
|
|
{
|
|
initialContext.close();
|
|
}
|
|
}
|
|
</code>
|
|
</pre>
|
|
|
|
</ol>
|
|
</body>
|
|
</html>
|