camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Camel > Load Balancer
Date Wed, 29 Aug 2012 09:08:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/2042/9/1/_/styles/combined.css?spaceKey=CAMEL&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/CAMEL/Load+Balancer">Load
Balancer</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~njiang">willem
jiang</a>
    </h4>
        <div id="versionComment">
        <b>Comment:</b>
        Fix the broken link.<br />
    </div>
        <br/>
                         <h4>Changes (1)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" > <br>The above example loads
balance requests from *direct:start* to one of the available *mock endpoint* instances, in
this case using a round robin policy. <br></td></tr>
            <tr><td class="diff-changed-lines" >For further examples of this pattern
look at [this junit test <span class="diff-changed-words">case|http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/<span
class="diff-added-chars"style="background-color: #dfd;">RoundRobin</span>LoadBalanceTest.java?view=markup]</span>
<br></td></tr>
            <tr><td class="diff-unchanged" > <br>h3. Failover <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <h3><a name="LoadBalancer-LoadBalancer"></a>Load Balancer</h3>

<p>The Load Balancer Pattern allows you to delegate to one of a number of endpoints
using a variety of different load balancing policies.</p>

<h3><a name="LoadBalancer-Builtinloadbalancingpolicies"></a>Built-in load
balancing policies</h3>

<p>Camel provides the following policies out-of-the-box:</p>
<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Policy </th>
<th class='confluenceTh'> Description </th>
</tr>
<tr>
<td class='confluenceTd'> <a href="http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/processor/loadbalancer/RoundRobinLoadBalancer.html"
class="external-link" rel="nofollow">Round Robin</a> </td>
<td class='confluenceTd'> The exchanges are selected from in a round robin fashion.
This is a well known and classic policy, which spreads the load evenly. </td>
</tr>
<tr>
<td class='confluenceTd'> <a href="http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/processor/loadbalancer/RandomLoadBalancer.html"
class="external-link" rel="nofollow">Random</a> </td>
<td class='confluenceTd'> A random endpoint is selected for each exchange. </td>
</tr>
<tr>
<td class='confluenceTd'> <a href="http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/processor/loadbalancer/StickyLoadBalancer.html"
class="external-link" rel="nofollow">Sticky</a> </td>
<td class='confluenceTd'> Sticky load balancing using an Expression to calculate a correlation
key to perform the sticky load balancing; rather like jsessionid in the web or JMSXGroupID
in JMS. </td>
</tr>
<tr>
<td class='confluenceTd'> <a href="http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/processor/loadbalancer/TopicLoadBalancer.html"
class="external-link" rel="nofollow">Topic</a> </td>
<td class='confluenceTd'> Topic which sends to all destinations (rather like JMS Topics)
</td>
</tr>
<tr>
<td class='confluenceTd'> <a href="http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/processor/loadbalancer/FailOverLoadBalancer.html"
class="external-link" rel="nofollow">Failover</a> </td>
<td class='confluenceTd'> <b>Camel 2.0:</b> In case of failures the exchange
will be tried on the next endpoint. </td>
</tr>
<tr>
<td class='confluenceTd'> Weighted Round-Robin </td>
<td class='confluenceTd'> <b>Camel 2.5:</b> The weighted load balancing
policy allows you to specify a processing load distribution ratio for each server with respect
to the others.  In addition to the weight, endpoint selection is then further refined using
<b>round-robin</b> distribution based on weight. </td>
</tr>
<tr>
<td class='confluenceTd'> Weighted Random </td>
<td class='confluenceTd'> <b>Camel 2.5:</b> The weighted load balancing
policy allows you to specify a processing load distribution ratio for each server with respect
to others.In addition to the weight, endpoint selection is then further refined using <b>random</b>
distribution based on weight. </td>
</tr>
<tr>
<td class='confluenceTd'> Custom </td>
<td class='confluenceTd'> <b>Camel 2.8:</b> From Camel 2.8 onwards the preferred
way of using a custom <a href="/confluence/display/CAMEL/Load+Balancer" title="Load Balancer">Load
Balancer</a> is to use this policy, instead of using the @deprecated <tt>ref</tt>
attribute. </td>
</tr>
</tbody></table>
</div>


<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/check.gif" width="16" height="16"
align="absmiddle" alt="" border="0"></td><td><b>Load balancing HTTP endpoints</b><br
/>If you are proxying and load balancing HTTP, then see <a href="/confluence/display/CAMEL/How+to+use+Camel+as+a+HTTP+proxy+between+a+client+and+server"
title="How to use Camel as a HTTP proxy between a client and server">this page</a>
for more details.</td></tr></table></div>

<h3><a name="LoadBalancer-RoundRobin"></a>Round Robin</h3>

<p>The round robin load balancer is not meant to work with failover, for that you should
use the dedicated <b>failover</b> load balancer. The round robin load balancer
will only change to next endpoint per message.</p>

<p>The round robin load balancer is stateful as it keeps state of which endpoint to
use next time.</p>

<p><b>Using the <a href="/confluence/display/CAMEL/Fluent+Builders" title="Fluent
Builders">Fluent Builders</a></b></p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">from(<span class="code-quote">"direct:start"</span>).loadBalance().
roundRobin().to(<span class="code-quote">"mock:x"</span>, <span class="code-quote">"mock:y"</span>,
<span class="code-quote">"mock:z"</span>);
</pre>
</div></div>

<p><b>Using the Spring configuration</b></p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
&lt;camelContext id=<span class="code-quote">"camel"</span> xmlns=<span
class="code-quote">"http:<span class="code-comment">//camel.apache.org/schema/spring"</span>&gt;
</span>  &lt;route&gt;
    &lt;from uri=<span class="code-quote">"direct:start"</span>/&gt;
    &lt;loadBalance&gt;        
        &lt;roundRobin/&gt;
        &lt;to uri=<span class="code-quote">"mock:x"</span>/&gt;     
  
        &lt;to uri=<span class="code-quote">"mock:y"</span>/&gt;     
 
        &lt;to uri=<span class="code-quote">"mock:z"</span>/&gt;     
           
    &lt;/loadBalance&gt;
  &lt;/route&gt;
&lt;/camelContext&gt;
</pre>
</div></div>

<p>The above example loads balance requests from <b>direct:start</b> to
one of the available <b>mock endpoint</b> instances, in this case using a round
robin policy.<br/>
For further examples of this pattern look at <a href="http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/RoundRobinLoadBalanceTest.java?view=markup"
class="external-link" rel="nofollow">this junit test case</a></p>

<h3><a name="LoadBalancer-Failover"></a>Failover</h3>
<p><b>Available as of Camel 2.0</b><br/>
The <tt>failover</tt> load balancer is capable of trying the next processor in
case an <a href="/confluence/display/CAMEL/Exchange" title="Exchange">Exchange</a>
failed with an <tt>exception</tt> during processing.<br/>
You can constrain the <tt>failover</tt> to activate only when one exception of
a list you specify occurs. If you do not specify a list any exception will cause fail over
to occur.  This balancer uses the same strategy for matching exceptions as the <a href="/confluence/display/CAMEL/Exception+Clause"
title="Exception Clause">Exception Clause</a> does for the <b>onException</b>.</p>

<div class='panelMacro'><table class='infoMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/information.gif" width="16"
height="16" align="absmiddle" alt="" border="0"></td><td><b>Enable stream
caching if using streams</b><br />If you use streaming then you should enable
<a href="/confluence/display/CAMEL/Stream+caching" title="Stream caching">Stream caching</a>
when using the failover load balancer. This is needed so the stream can be re-read after failing
over to the next processor.</td></tr></table></div>

<p>Failover offers the following options:</p>
<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Option </th>
<th class='confluenceTh'> Type </th>
<th class='confluenceTh'> Default </th>
<th class='confluenceTh'> Description </th>
</tr>
<tr>
<td class='confluenceTd'> inheritErrorHandler </td>
<td class='confluenceTd'> boolean </td>
<td class='confluenceTd'> true </td>
<td class='confluenceTd'> <b>Camel 2.3:</b> Whether or not the <a href="/confluence/display/CAMEL/Error+Handler"
title="Error Handler">Error Handler</a> configured on the route should be used. Disable
this if you want failover to transfer immediately to the next endpoint. On the other hand,
if you have this option enabled, then Camel will first let the <a href="/confluence/display/CAMEL/Error+Handler"
title="Error Handler">Error Handler</a> try to process the message. The <a href="/confluence/display/CAMEL/Error+Handler"
title="Error Handler">Error Handler</a> may have been configured to redeliver and
use delays between attempts. If you have enabled a number of redeliveries then Camel will
try to redeliver to the <b>same</b> endpoint, and only fail over to the next endpoint,
when the <a href="/confluence/display/CAMEL/Error+Handler" title="Error Handler">Error
Handler</a> is exhausted. </td>
</tr>
<tr>
<td class='confluenceTd'> maximumFailoverAttempts </td>
<td class='confluenceTd'> int </td>
<td class='confluenceTd'> -1 </td>
<td class='confluenceTd'> <b>Camel 2.3:</b> A value to indicate after X
failover attempts we should exhaust (give up). Use -1 to indicate never give up and continuously
try to failover. Use 0 to never failover. And use e.g. 3 to failover at most 3 times before
giving up. This option can be used whether or not roundRobin is enabled or not. </td>
</tr>
<tr>
<td class='confluenceTd'> roundRobin </td>
<td class='confluenceTd'> boolean </td>
<td class='confluenceTd'> false </td>
<td class='confluenceTd'> <b>Camel 2.3:</b> Whether or not the <tt>failover</tt>
load balancer should operate in round robin mode or not. If not, then it will <b>always</b>
start from the first endpoint when a new message is to be processed. In other words it restart
from the top for every message. If round robin is enabled, then it keeps state and will continue
with the next endpoint in a round robin fashion. When using round robin it will not <em>stick</em>
to last known good endpoint, it will always pick the next endpoint to use. </td>
</tr>
</tbody></table>
</div>


<p><b>Camel 2.2 or older behavior</b><br/>
The current implementation of failover load balancer uses simple logic which <b>always</b>
tries the first endpoint, and in case of an exception being thrown it tries the next in the
list, and so forth. It has no state, and the next message will thus <b>always</b>
start with the first endpoint.</p>

<p><b>Camel 2.3 onwards behavior</b><br/>
The <tt>failover</tt> load balancer now supports round robin mode, which allows
you to failover in a round robin fashion. See the <tt>roundRobin</tt> option.</p>

<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/warning.gif" width="16" height="16"
align="absmiddle" alt="" border="0"></td><td><b>Redelivery must be enabled</b><br
/>In Camel 2.2 or older the failover load balancer requires you have enabled Camel <a
href="/confluence/display/CAMEL/Error+Handler" title="Error Handler">Error Handler</a>
to use redelivery. In Camel 2.3 onwards this is not required as such, as you can mix and match.
See the <tt>inheritErrorHandler</tt> option.</td></tr></table></div>

<p>Here is a sample to failover only if a <tt>IOException</tt> related exception
was thrown:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">from(<span class="code-quote">"direct:start"</span>)
    <span class="code-comment">// here we will load balance <span class="code-keyword">if</span>
IOException was thrown
</span>    <span class="code-comment">// any other kind of exception will result
in the Exchange as failed
</span>    <span class="code-comment">// to failover over any kind of exception
we can just omit the exception
</span>    <span class="code-comment">// in the failOver DSL
</span>    .loadBalance().failover(IOException.class)
        .to(<span class="code-quote">"direct:x"</span>, <span class="code-quote">"direct:y"</span>,
<span class="code-quote">"direct:z"</span>);
</pre>
</div></div> 

<p>You can specify multiple exceptions to failover as the option is varargs, for instance:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-comment">// enable redelivery so failover can react
</span>errorHandler(defaultErrorHandler().maximumRedeliveries(5));

from(<span class="code-quote">"direct:foo"</span>).
    loadBalance().failover(IOException.class, MyOtherException.class)
        .to(<span class="code-quote">"direct:a"</span>, <span class="code-quote">"direct:b"</span>);
</pre>
</div></div>

<h4><a name="LoadBalancer-UsingfailoverinSpringDSL"></a>Using failover in
Spring DSL</h4>
<p>Failover can also be used from Spring DSL and you configure it as:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
   <span class="code-tag">&lt;route errorHandlerRef=<span class="code-quote">"myErrorHandler"</span>&gt;</span>
      <span class="code-tag">&lt;from uri=<span class="code-quote">"direct:foo"</span>/&gt;</span>
      <span class="code-tag">&lt;loadBalance&gt;</span>
          <span class="code-tag">&lt;failover&gt;</span>
              <span class="code-tag">&lt;exception&gt;</span>java.io.IOException<span
class="code-tag">&lt;/exception&gt;</span>
              <span class="code-tag">&lt;exception&gt;</span>com.mycompany.MyOtherException<span
class="code-tag">&lt;/exception&gt;</span>
          <span class="code-tag">&lt;/failover&gt;</span>
          <span class="code-tag">&lt;to uri=<span class="code-quote">"direct:a"</span>/&gt;</span>
          <span class="code-tag">&lt;to uri=<span class="code-quote">"direct:b"</span>/&gt;</span>
      <span class="code-tag">&lt;/loadBalance&gt;</span>
    <span class="code-tag">&lt;/route&gt;</span>
</pre>
</div></div>

<h4><a name="LoadBalancer-Usingfailoverinroundrobinmode"></a>Using failover
in round robin mode</h4>

<p>An example using Java DSL:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">from(<span class="code-quote">"direct:start"</span>)
    <span class="code-comment">// Use failover load balancer in stateful round robin
mode
</span>    <span class="code-comment">// which mean it will failover immediately
in <span class="code-keyword">case</span> of an exception
</span>    <span class="code-comment">// as it does NOT inherit error handler.
It will also keep retrying as
</span>    <span class="code-comment">// its configured to newer exhaust.
</span>    .loadBalance().failover(-1, <span class="code-keyword">false</span>,
<span class="code-keyword">true</span>).
        to(<span class="code-quote">"direct:bad"</span>, <span class="code-quote">"direct:bad2"</span>,
<span class="code-quote">"direct:good"</span>, <span class="code-quote">"direct:good2"</span>);
</pre>
</div></div> 

<p>And the same example using Spring XML:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml"><span class="code-tag">&lt;route&gt;</span>
    <span class="code-tag">&lt;from uri=<span class="code-quote">"direct:start"</span>/&gt;</span>
    <span class="code-tag">&lt;loadBalance&gt;</span>
        &lt;!-- failover using stateful round robin,
             which will keep retrying forever those 4 endpoints until success.
             You can set the maximumFailoverAttempt to break out after X attempts --&gt;
        <span class="code-tag">&lt;failover roundRobin=<span class="code-quote">"true"</span>/&gt;</span>
        <span class="code-tag">&lt;to uri=<span class="code-quote">"direct:bad"</span>/&gt;</span>
        <span class="code-tag">&lt;to uri=<span class="code-quote">"direct:bad2"</span>/&gt;</span>
        <span class="code-tag">&lt;to uri=<span class="code-quote">"direct:good"</span>/&gt;</span>
        <span class="code-tag">&lt;to uri=<span class="code-quote">"direct:good2"</span>/&gt;</span>
    <span class="code-tag">&lt;/loadBalance&gt;</span>
<span class="code-tag">&lt;/route&gt;</span>
</pre>
</div></div> 

<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/check.gif" width="16" height="16"
align="absmiddle" alt="" border="0"></td><td><b>Disabled inheritErrorHandler</b><br
/>You can configure <tt>inheritErrorHandler=false</tt> if you want to failover
to the next endpoint as fast as possible. By disabling the <a href="/confluence/display/CAMEL/Error+Handler"
title="Error Handler">Error Handler</a> you ensure it does not <em>intervene</em>
which allows the <tt>failover</tt> load balancer to handle failover asap. By also
enabling <tt>roundRobin</tt> mode, then it will keep retrying until it success.
You can then configure the <tt>maximumFailoverAttempts</tt> option to a high value
to let it eventually exhaust (give up) and fail.</td></tr></table></div>

<h3><a name="LoadBalancer-WeightedRoundRobinandRandomLoadBalancing"></a>Weighted
Round-Robin and Random Load Balancing</h3>
<p><b>Available as of Camel 2.5</b></p>

<p>In many enterprise environments where server nodes of unequal processing power &amp;
performance characteristics are utilized to host services and processing endpoints, it is
frequently necessary to distribute processing load based on their individual server capabilities
so that some endpoints are not unfairly burdened with requests. Obviously simple round-robin
or random load balancing do not alleviate problems of this nature. A Weighted Round-Robin
and/or Weighted Random load balancer can be used to address this problem.</p>

<p>The weighted load balancing policy allows you to specify a processing load distribution
ratio for each server with respect to others. You can specify this as a positive processing
weight for each server. A larger number indicates that the server can handle a larger load.
The weight is utilized to determine the payload distribution ratio to different processing
endpoints with respect to others.</p>

<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/check.gif" width="16" height="16"
align="absmiddle" alt="" border="0"></td><td><b>Disabled inheritErrorHandler</b><br
/>As of Camel 2.6, the Weighted Load balancer usage has been further simplified, there
is no need to send in distributionRatio as a List&lt;Integer&gt;. It can be simply
sent as a delimited String of integer weights separated by a delimiter of choice.</td></tr></table></div>

<p>The parameters that can be used are</p>

<p><b>In Camel 2.5</b></p>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Option </th>
<th class='confluenceTh'> Type </th>
<th class='confluenceTh'> Default </th>
<th class='confluenceTh'> Description </th>
</tr>
<tr>
<td class='confluenceTd'> roundRobin </td>
<td class='confluenceTd'> boolean </td>
<td class='confluenceTd'> false </td>
<td class='confluenceTd'> The default value for round-robin is false. In the absence
of this setting or parameter the load balancing algorithm used is random.</td>
</tr>
<tr>
<td class='confluenceTd'> distributionRatio </td>
<td class='confluenceTd'> List&lt;Integer&gt; </td>
<td class='confluenceTd'> none </td>
<td class='confluenceTd'> The distributionRatio is a list consisting on integer weights
passed in as a parameter. The distributionRatio must match the number of endpoints and/or
processors specified in the load balancer list. In Camel 2.5 if endpoints do not match ratios,
then a best effort distribution is attempted. </td>
</tr>
</tbody></table>
</div>


<p><b>Available In Camel 2.6</b></p>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Option </th>
<th class='confluenceTh'> Type </th>
<th class='confluenceTh'> Default </th>
<th class='confluenceTh'> Description </th>
</tr>
<tr>
<td class='confluenceTd'> roundRobin </td>
<td class='confluenceTd'> boolean </td>
<td class='confluenceTd'> false </td>
<td class='confluenceTd'> The default value for round-robin is false. In the absence
of this setting or parameter the load balancing algorithm used is random.</td>
</tr>
<tr>
<td class='confluenceTd'> distributionRatio </td>
<td class='confluenceTd'> String </td>
<td class='confluenceTd'> none </td>
<td class='confluenceTd'> The distributionRatio is a delimited String consisting on
integer weights separated by delimiters for example "2,3,5". The distributionRatio must match
the number of endpoints and/or processors specified in the load balancer list. </td>
</tr>
<tr>
<td class='confluenceTd'> distributionRatioDelimiter </td>
<td class='confluenceTd'> String </td>
<td class='confluenceTd'> , </td>
<td class='confluenceTd'> The distributionRatioDelimiter is the delimiter used to specify
the distributionRatio. If this attribute is not specified a default delimiter "," is expected
as the delimiter used for specifying the distributionRatio. </td>
</tr>
</tbody></table>
</div>


<h4><a name="LoadBalancer-UsingWeightedroundrobin%26randomloadbalancing"></a>Using
Weighted round-robin &amp; random load balancing</h4>

<p><b>In Camel 2.5</b></p>

<p>An example using Java DSL:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
ArrayList&lt;integer&gt; distributionRatio = <span class="code-keyword">new</span>
ArrayList&lt;integer&gt;();
distributionRatio.add(4);
distributionRatio.add(2);
distributionRatio.add(1);

<span class="code-comment">// round-robin
</span>from(<span class="code-quote">"direct:start"</span>)
    .loadBalance().weighted(<span class="code-keyword">true</span>, distributionRatio)
    .to(<span class="code-quote">"mock:x"</span>, <span class="code-quote">"mock:y"</span>,
<span class="code-quote">"mock:z"</span>);

<span class="code-comment">//random
</span>from(<span class="code-quote">"direct:start"</span>)
    .loadBalance().weighted(<span class="code-keyword">false</span>, distributionRatio)
    .to(<span class="code-quote">"mock:x"</span>, <span class="code-quote">"mock:y"</span>,
<span class="code-quote">"mock:z"</span>);
</pre>
</div></div>

<p>And the same example using Spring XML:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
    <span class="code-tag">&lt;route&gt;</span>
      <span class="code-tag">&lt;from uri=<span class="code-quote">"direct:start"</span>/&gt;</span>
      <span class="code-tag">&lt;loadBalance&gt;</span>
        <span class="code-tag">&lt;weighted roundRobin=<span class="code-quote">"false"</span>
distributionRatio=<span class="code-quote">"4 2 1"</span>/&gt;</span>
          <span class="code-tag">&lt;to uri=<span class="code-quote">"mock:x"</span>/&gt;</span>
          <span class="code-tag">&lt;to uri=<span class="code-quote">"mock:y"</span>/&gt;</span>
          <span class="code-tag">&lt;to uri=<span class="code-quote">"mock:z"</span>/&gt;</span>
      <span class="code-tag">&lt;/loadBalance&gt;</span>
    <span class="code-tag">&lt;/route&gt;</span>
</pre>
</div></div>

<p><b>Available In Camel 2.6</b></p>

<p>An example using Java DSL:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-comment">// round-robin
</span>from(<span class="code-quote">"direct:start"</span>)
    .loadBalance().weighted(<span class="code-keyword">true</span>, <span class="code-quote">"4:2:1"</span>
distributionRatioDelimiter=<span class="code-quote">":"</span>)
    .to(<span class="code-quote">"mock:x"</span>, <span class="code-quote">"mock:y"</span>,
<span class="code-quote">"mock:z"</span>);

<span class="code-comment">//random
</span>from(<span class="code-quote">"direct:start"</span>)
    .loadBalance().weighted(<span class="code-keyword">false</span>, <span
class="code-quote">"4,2,1"</span>)
    .to(<span class="code-quote">"mock:x"</span>, <span class="code-quote">"mock:y"</span>,
<span class="code-quote">"mock:z"</span>);
</pre>
</div></div>

<p>And the same example using Spring XML:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
    <span class="code-tag">&lt;route&gt;</span>
      <span class="code-tag">&lt;from uri=<span class="code-quote">"direct:start"</span>/&gt;</span>
      <span class="code-tag">&lt;loadBalance&gt;</span>
        <span class="code-tag">&lt;weighted roundRobin=<span class="code-quote">"false"</span>
distributionRatio=<span class="code-quote">"4-2-1"</span> distributionRatioDelimiter=<span
class="code-quote">"-"</span> /&gt;</span>
          <span class="code-tag">&lt;to uri=<span class="code-quote">"mock:x"</span>/&gt;</span>
          <span class="code-tag">&lt;to uri=<span class="code-quote">"mock:y"</span>/&gt;</span>
          <span class="code-tag">&lt;to uri=<span class="code-quote">"mock:z"</span>/&gt;</span>
      <span class="code-tag">&lt;/loadBalance&gt;</span>
    <span class="code-tag">&lt;/route&gt;</span>
</pre>
</div></div>


<h3><a name="LoadBalancer-CustomLoadBalancer"></a>Custom Load Balancer</h3>

<p>You can use a custom load balancer (eg your own implementation) also. </p>

<p>An example using Java DSL:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">from(<span class="code-quote">"direct:start"</span>)
    <span class="code-comment">// using our custom load balancer
</span>    .loadBalance(<span class="code-keyword">new</span> MyLoadBalancer())
    .to(<span class="code-quote">"mock:x"</span>, <span class="code-quote">"mock:y"</span>,
<span class="code-quote">"mock:z"</span>);
</pre>
</div></div> 

<p>And the same example using XML DSL:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml"><span class="code-tag"><span class="code-comment">&lt;!--
this is the implementation of our custom load balancer --&gt;</span></span>
<span class="code-tag">&lt;bean id=<span class="code-quote">"myBalancer"</span>
class=<span class="code-quote">"org.apache.camel.processor.CustomLoadBalanceTest$MyLoadBalancer"</span>/&gt;</span>

<span class="code-tag">&lt;camelContext xmlns=<span class="code-quote">"http://camel.apache.org/schema/spring"</span>&gt;</span>
  <span class="code-tag">&lt;route&gt;</span>
    <span class="code-tag">&lt;from uri=<span class="code-quote">"direct:start"</span>/&gt;</span>
    <span class="code-tag">&lt;loadBalance&gt;</span>
      <span class="code-tag"><span class="code-comment">&lt;!-- refer to my
custom load balancer --&gt;</span></span>
      <span class="code-tag">&lt;custom ref=<span class="code-quote">"myBalancer"</span>/&gt;</span>
      <span class="code-tag"><span class="code-comment">&lt;!-- these are
the endpoints to balancer --&gt;</span></span>
      <span class="code-tag">&lt;to uri=<span class="code-quote">"mock:x"</span>/&gt;</span>
      <span class="code-tag">&lt;to uri=<span class="code-quote">"mock:y"</span>/&gt;</span>
      <span class="code-tag">&lt;to uri=<span class="code-quote">"mock:z"</span>/&gt;</span>
    <span class="code-tag">&lt;/loadBalance&gt;</span>
  <span class="code-tag">&lt;/route&gt;</span>
<span class="code-tag">&lt;/camelContext&gt;</span>
</pre>
</div></div> 

<p>Notice in the XML DSL above we use &lt;custom&gt; which is only available
in <b>Camel 2.8</b> onwards. In older releases you would have to do as follows
instead:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
      <span class="code-tag">&lt;loadBalance ref=<span class="code-quote">"myBalancer"</span>&gt;</span>
        <span class="code-tag"><span class="code-comment">&lt;!-- these are
the endpoints to balancer --&gt;</span></span>
        <span class="code-tag">&lt;to uri=<span class="code-quote">"mock:x"</span>/&gt;</span>
        <span class="code-tag">&lt;to uri=<span class="code-quote">"mock:y"</span>/&gt;</span>
        <span class="code-tag">&lt;to uri=<span class="code-quote">"mock:z"</span>/&gt;</span>
      <span class="code-tag">&lt;/loadBalance&gt;</span>
</pre>
</div></div>

<p>To implement a custom load balancer you can extend some support classes such as <tt>LoadBalancerSupport</tt>
and <tt>SimpleLoadBalancerSupport</tt>. The former supports the asynchronous routing
engine, and the latter does not. Here is an example:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>Custom load balancer implementation</b></div><div
class="codeContent panelContent">
<pre class="code-java"><span class="code-keyword">public</span> <span
class="code-keyword">static</span> class MyLoadBalancer <span class="code-keyword">extends</span>
LoadBalancerSupport {

    <span class="code-keyword">public</span> <span class="code-object">boolean</span>
process(Exchange exchange, AsyncCallback callback) {
        <span class="code-object">String</span> body = exchange.getIn().getBody(<span
class="code-object">String</span>.class);
        <span class="code-keyword">try</span> {
            <span class="code-keyword">if</span> (<span class="code-quote">"x"</span>.equals(body))
{
                getProcessors().get(0).process(exchange);
            } <span class="code-keyword">else</span> <span class="code-keyword">if</span>
(<span class="code-quote">"y"</span>.equals(body)) {
                getProcessors().get(1).process(exchange);
            } <span class="code-keyword">else</span> {
                getProcessors().get(2).process(exchange);
            }
        } <span class="code-keyword">catch</span> (Throwable e) {
            exchange.setException(e);
        }
        callback.done(<span class="code-keyword">true</span>);
        <span class="code-keyword">return</span> <span class="code-keyword">true</span>;
    }
}
</pre>
</div></div> 


<h4><a name="LoadBalancer-UsingThisPattern"></a>Using This Pattern</h4>

<p>If you would like to use this EIP Pattern then please read the <a href="/confluence/display/CAMEL/Getting+Started"
title="Getting Started">Getting Started</a>, you may also find the <a href="/confluence/display/CAMEL/Architecture"
title="Architecture">Architecture</a> useful particularly the description of <a
href="/confluence/display/CAMEL/Endpoint" title="Endpoint">Endpoint</a> and <a
href="/confluence/display/CAMEL/URIs" title="URIs">URIs</a>. Then you could try out
some of the <a href="/confluence/display/CAMEL/Examples" title="Examples">Examples</a>
first before trying this pattern out.</p>
    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://cwiki.apache.org/confluence/display/CAMEL/Load+Balancer">View
Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=81397&revisedVersion=32&originalVersion=31">View
Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/CAMEL/Load+Balancer?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message