Load Balancer - 6.3

Talend ESB Mediation Developer Guide

EnrichVersion
6.3
EnrichProdName
Talend Data Fabric
Talend Data Services Platform
Talend ESB
Talend MDM Platform
Talend Open Studio for ESB
Talend Real-Time Big Data Platform
task
Design and Development
EnrichPlatform
Talend ESB

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

Built-in load balancing policies

Camel provides the following policies out-of-the-box:

Policy

Description

Round Robin

The exchanges are selected from in a round robin fashion. This is a well known and classic policy, which spreads the load evenly.

Random

A random endpoint is selected for each exchange.

Sticky

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.

Topic

Topic which sends to all destinations (rather like JMS Topics).

Failover

In case of failures the exchange is tried on the next endpoint.

Weighted Round Robin

Camel 2.5: 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 round-robin distribution based on weight.

Weighted Random

Camel 2.5: 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 random distribution based on weight.

Custom

Camel 2.8: From Camel 2.8 onwards the preferred way of using a custom Load Balancer is to use this policy, instead of using the @deprecated ref attribute.

Circuit Breaker

Camel 2.14: Implements the Circuit Breaker pattern as described in "Release it!" book.

Important

If you are proxying and load balancing HTTP, then see this page for more details.

Round Robin

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

The round robin load balancer is stateful as it keeps state which endpoint to use next time.

Using the Fluent Builders

from("direct:start").loadBalance().
   roundRobin().to("mock:x", "mock:y", "mock:z");

Using the Spring configuration

<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
  <route>
    <from uri="direct:start"/>
    <loadBalance>        
        <roundRobin/>
        <to uri="mock:x"/>        
        <to uri="mock:y"/>       
        <to uri="mock:z"/>                 
    </loadBalance>
  </route>
</camelContext>

So the above example will load balance requests from direct:start to one of the available mock endpoint instances, in this case using a round robbin policy. For further examples of this pattern in use see this JUnit test case.

Failover

The failover load balancer is capable of trying the next processor in case an Exchange failed with an exception during processing. You can configure the failover with a list of specific exception to only failover. If you do not specify any exceptions it will failover over any exceptions. It uses the same strategy for matching exceptions as the Exception Clause does for the onException.

Important

If you use streaming then you should enable Stream caching when using the failover load balancer. This is needed so the stream can be re-read when failing over.

It has the following options:

Option

Type

Default

Description

inheritErrorHandler

boolean

true

Whether or not the Error Handler configured on the route should be used or not. You can disable it if you want the failover to trigger immediately and failover to the next endpoint. On the other hand if you have this option enabled, then Camel will first let the Error Handler try to process the message. The Error Handler may have been configured to redelivery and use delays between attempts. If you have enabled a number of redeliveries then Camel will try to redeliver to the same endpoint, and only failover to the next endpoint, when the Error Handler is exhausted.

maximumFailover-Attempts

int

-1

A value to indicate after X failver attempts we should exhaust (give up). Use -1 to indicate newer give up and always try to failover. Use 0 to newer failover. And use e.g. 3 to failover at most 3 times before giving up. This option can be used whether or not round robin is enabled or not.

roundRobin

boolean

false

Whether or not the failover load balancer should operate in round robin mode or not. If not, then it will always 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 stick to last known good endpoint, it will always pick the next endpoint to use.

The failover load balancer supports round robin mode, which allows you to failover in a round robin fashion. See the roundRobin option.

Here is a sample to failover only if a IOException related exception was thrown:

from("direct:start")
    // here we will load balance if IOException was thrown
    // any other kind of exception will result in the Exchange as failed
    // to failover over any kind of exception we can just omit 
    // the exception in the failOver DSL
    .loadBalance().failover(IOException.class)
        .to("direct:x", "direct:y", "direct:z");

You can specify multiple exceptions to failover as the option is varargs, for instance:

// enable redelivery so failover can react
errorHandler(defaultErrorHandler().maximumRedeliveries(5));

from("direct:foo").
    loadBalance().failover(IOException.class, MyOtherException.class)
        .to("direct:a", "direct:b");

Using failover in Spring DSL

Failover can also be used from Spring DSL and you configure it as:

<route errorHandlerRef="myErrorHandler">
      <from uri="direct:foo"/>
      <loadBalance>
          <failover>
              <exception>java.io.IOException</exception>
              <exception>com.mycompany.MyOtherException</exception>
          </failover>
          <to uri="direct:a"/>
          <to uri="direct:b"/>
      </loadBalance>
</route>

Using failover in round robin mode

An example using Java DSL:

from("direct:start")
    // Use failover load balancer in stateful round robin mode
    // which mean it will failover immediately in case of an exception
    // as it does NOT inherit error handler. It will also keep retrying as
    // it is configured to newer exhaust.
    .loadBalance().failover(-1, false, true).
        to("direct:bad", "direct:bad2", "direct:good", "direct:good2");

And the same example using Spring XML:

<route>
    <from uri="direct:start"/>
    <loadBalance>
        <!-- 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 -->
        <failover roundRobin="true"/>
        <to uri="direct:bad"/>
        <to uri="direct:bad2"/>
        <to uri="direct:good"/>
        <to uri="direct:good2"/>
    </loadBalance>
</route>

Weighted Round-Robin and Random Load Balancing

In many enterprise environments where server nodes of unequal processing power & 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.

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.

The parameters that can be used are

Option

Type

Default

Description

roundRobin

boolean

false

The default value for round-robin is false. In the absence of this setting or parameter the load balancing algorithm used is random.

distributionRatio

String

none

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.

distributionRatio-Delimiter

String

,

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.

See the Camel website for examples on using this load balancer.

Circuit Breaker

The Circuit Breaker load balancer is a stateful pattern that monitors all calls for certain exceptions. Initially the Circuit Breaker is in closed state and passes all messages. If there are failures and the threshold is reached, it moves to open state and rejects all calls until halfOpenAfter timeout is reached. After this timeout is reached, if there is a new call, it will pass and if the result is success the Circuit Breaker will move to closed state, or to open state if there was an error.

An example using Java DSL:

from("direct:start").loadBalance()
    .circuitBreaker(2, 1000L, MyCustomException.class)
    .to("mock:result");

And the same example using Spring XML:

<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
    <route>
    <from uri="direct:start"/>
    <loadBalance>
        <circuitBreaker threshold="2" halfOpenAfter="1000">
            <exception>MyCustomException</exception>
        </circuitBreaker>
        <to uri="mock:result"/>
    </loadBalance>
</route>
</camelContext>