The load balancer pattern allows you to delegate message processing to one of several endpoints, using a variety of different load-balancing policies.
The Fuse Mediation Router load balancer supports the following load-balancing policies:
The round robin load-balancing policy cycles through all of the target endpoints,
sending each incoming message to the next endpoint in the cycle. For example, if the list of
target endpoints is, mock:x, mock:y, mock:z, then the
incoming messages are sent to the following sequence of endpoints: mock:x,
mock:y, mock:z, mock:x, mock:y,
mock:z, and so on.
You can specify the round robin load-balancing policy in XML, as follows:
<camelContext 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>
The random load-balancing policy chooses the target endpoint randomly from the specified list.
You can specify the random load-balancing policy in XML, as follows:
<camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <loadBalance> <random/> <to uri="mock:x"/> <to uri="mock:y"/> <to uri="mock:z"/> </loadBalance> </route> </camelContext>
The sticky load-balancing policy directs the In message to an endpoint that is chosen by calculating a hash value from a specified expression. The advantage of this load-balancing policy is that expressions of the same value are always sent to the same server. For example, by calculating the hash value from a header that contains a username, you ensure that messages from a particular user are always sent to the same target endpoint. Another useful approach is to specify an expression that extracts the session ID from an incoming message. This ensures that all messages belonging to the same session are sent to the same target endpoint.
You can specify the sticky load-balancing policy in XML, as follows:
<camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <loadBalance> <sticky> <expression> <simple>header.username</simple> </expression> </sticky> <to uri="mock:x"/> <to uri="mock:y"/> <to uri="mock:z"/> </loadBalance> </route> </camelContext>
The topic load-balancing policy sends a copy of each In message to all of the listed destination endpoints (effectively broadcasting the message to all of the destinations, like a JMS topic).
You can specify the topic load-balancing policy, as follows:
<camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <loadBalance> <topic/> <to uri="mock:x"/> <to uri="mock:y"/> <to uri="mock:z"/> </loadBalance> </route> </camelContext>
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 exceptions that trigger failover. If you do not specify any
exceptions, failover is triggered by any exception. The failover load balancer uses the
same strategy for matching exceptions as the onException exception
clause.
![]() | Enable stream caching if using streams |
|---|---|
If you use streaming, you should enable Stream Caching when using the failover load balancer. This is needed so the stream can be re-read when failing over. |
The failover load balancer supports options in Table 16.5.
Table 16.5. Failover load balancing options
| Option | Type | Default | Description |
|---|---|---|---|
inheritErrorHandler
|
boolean
|
true
|
Specifies whether to use the
For example, the |
maximumFailoverAttempts
|
int
|
-1 |
Specifies the maximum number of
attempts to fail over to a new endpoint. The value, |
roundRobin
|
boolean
|
false
|
Specifies whether the
|
The following example is configured to fail over, only if an
IOException exception is thrown:
<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>
The following example shows how to fail over in round robin mode:
<route>
<from uri="direct:start"/>
<loadBalance>
<!-- failover using stateful round robin,
which will keep retrying the 4 endpoints indefinitely.
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>In many enterprise environments, where server nodes of unequal processing power are hosting services, it is usually preferable to distribute the load in accordance with the individual server processing capacities. A weighted round robin algorithm or a weighted random algorithm 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 the others. You can specify this value as a positive processing weight for each server. A larger number indicates that the server can handle a larger load. The processing weight is used to determine the payload distribution ratio of each processing endpoint with respect to the others.
The parameters that can be used are
Table 16.6. Weighted options
| 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. |
distributionRatioDelimiter
|
String
| , | The distributionRatioDelimiter is the delimiter used to specify the
distributionRatio. If this attribute is not specified, comma
, is the default delimiter. |
The following examples show how to define a weighted round-robin route and a weighted random route:
<!-- round-robin --> <route> <from uri="direct:start"/> <loadBalance> <weighted roundRobin="true" distributionRatio="4:2:1" distributionRatioDelimiter=":" /> <to uri="mock:x"/> <to uri="mock:y"/> <to uri="mock:z"/> </loadBalance> </route>
You can use a custom load balancer that you implement.
An example:
<!-- this is the implementation of our custom load balancer --> <bean id="myBalancer" class="org.apache.camel.processor.CustomLoadBalanceTest$MyLoadBalancer"/> <camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <loadBalance> <!-- refer to my custom load balancer --> <custom ref="myBalancer"/> <!-- these are the endpoints to balancer --> <to uri="mock:x"/> <to uri="mock:y"/> <to uri="mock:z"/> </loadBalance> </route> </camelContext>
To implement a custom load balancer you can extend one of the support classes such as
LoadBalancerSupport or SimpleLoadBalancerSupport.
LoadBalancerSupport supports the asynchronous routing engine.
SimpleLoadBalancerSupport does not.
The following is is an example custom load balancer:
public static class MyLoadBalancer extends LoadBalancerSupport {
public boolean process(Exchange exchange, AsyncCallback callback) {
String body = exchange.getIn().getBody(String.class);
try {
if ("x".equals(body)) {
getProcessors().get(0).process(exchange);
} else if ("y".equals(body)) {
getProcessors().get(1).process(exchange);
} else {
getProcessors().get(2).process(exchange);
}
} catch (Throwable e) {
exchange.setException(e);
}
callback.done(true);
return true;
}
}





![[Important]](imagesdb/important.gif)


