Load balancing is a technique to distribute workload across computers or other resources. This helps us to make best use of our resources thus maximize throughput, minimize response time, and avoid overload.
Suppose your application is hosted in a cluster of machines where each one has the ability to process the incoming message then you can distribute the messages received using Camel’s load balancer so that no one machine is overloaded.
This example uses the following frameworks:
- Maven 3.2.3
- Apache Camel 2.15.1
- Spring 4.1.5.RELEASE
- Eclipse as the IDE, version Luna 4.4.1.
Dependencies
We are just relying camel’s core components, the spring based components and the logger component in case you want to log something so our pom.xml
consists of:
camel-core
– camel core components like timer, bean etcslf4j-api
– in case you want to use logslf4j-log4j12
– if you want to use log4j as the slf4j implementationcamel-stream
– for printing the messages to consolespring-context
andspring-core
– for spring supportcamel-spring
– include it if you want to define route in spring
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.javarticles.camel</groupId> <artifactId>camelContentBasedRouting</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-core</artifactId> <version>2.15.2</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.12</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.12</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.1.5.RELEASE</version> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-spring</artifactId> <version>2.15.2</version> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-stream</artifactId> <version>2.15.2</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.1.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.1.5.RELEASE</version> </dependency> </dependencies> </project>
Camel Load Balancer Using Round Robin Strategy
Camel load balancer allows you to delegate to one of a number of endpoints using a variety of different load balancing policies. Let’s see an example load balancer that uses the round robin strategy. In a round robin strategy, the first message goes to the first endpoint, the second to the second endpoint, the third to the third endpoint, the fourth back will repeat itself from the first endpoint, and so on.
CamelLoadbalanceRoundRobinExample:
package com.javarticles.camel; import org.apache.camel.CamelContext; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.impl.DefaultCamelContext; public class CamelLoadbalanceRoundRobinExample { public static void main(String[] args) throws Exception { CamelContext camelContext = new DefaultCamelContext(); try { camelContext.addRoutes(new RouteBuilder() { public void configure() { from("timer:myTimer?period=1s") .loadBalance() .roundRobin() .to("direct:a") .to("direct:b") .to("direct:c"); from("direct:a") .setBody() .constant("Endpoint Direct a") .to("stream:out"); from("direct:b") .setBody() .constant("Endpoint Direct b") .to("stream:out"); from("direct:c") .setBody() .constant("Endpoint Direct c") .to("stream:out"); } }); camelContext.start(); Thread.sleep(10000); } finally { camelContext.stop(); } } }
Round robin strategy is the simplest of the pre-defined strategies, as you can see, The first message is sent to the “direct:a” endpoint, and the next would go to “direct:b” and then to “direct:c”. The fourth message would start over with “direct:a”, and so forth.
Output:
Endpoint Direct a Endpoint Direct b Endpoint Direct c Endpoint Direct a Endpoint Direct b Endpoint Direct c Endpoint Direct a Endpoint Direct b Endpoint Direct c
Load Balancer Using Random Strategy
When the load balancer receives a message, it depends on the load balancing strategy to decide which Processor to chose to process the message. We have seen the round robin strategy. In this example, we will see random load balancing strategy. As the name suggests, it chooses a processor randomly. In java DSL, we will call method random()
to set the random strategy.
CamelLoadbalanceRandomExample:
package com.javarticles.camel; import org.apache.camel.CamelContext; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.impl.DefaultCamelContext; public class CamelLoadbalanceRandomExample { public static void main(String[] args) throws Exception { CamelContext camelContext = new DefaultCamelContext(); try { camelContext.addRoutes(new RouteBuilder() { public void configure() { from("timer:myTimer?period=1s") .loadBalance() .random() .to("direct:a") .to("direct:b") .to("direct:c"); from("direct:a") .setBody() .constant("Endpoint Direct a") .to("stream:out"); from("direct:b") .setBody() .constant("Endpoint Direct b") .to("stream:out"); from("direct:c") .setBody() .constant("Endpoint Direct c") .to("stream:out"); } }); camelContext.start(); Thread.sleep(10000); } finally { camelContext.stop(); } } }
Output:
Endpoint Direct b Endpoint Direct b Endpoint Direct a Endpoint Direct c Endpoint Direct b Endpoint Direct c Endpoint Direct b Endpoint Direct a Endpoint Direct a
Load Balancing Using Spring DSL
Here is the equivalent route in spring DSL. The endpoints that are load balanced will be declared within <loadBalance>
element. The first element will define the load balancing strategy. Our strategy is round robin so we will simply add an empty tag <roundRobin />. If it is random strategy, you need to add <roundRobin />.
loadBalancingRoundRobinCamelContext.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> <camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="timer:myTimer?period=1s" /> <loadBalance> <roundRobin /> <to uri="direct:a" /> <to uri="direct:b" /> <to uri="direct:c" /> </loadBalance> </route> <route> <from uri="direct:a" /> <setBody> <constant>Endpoint Direct a</constant> </setBody> <to uri="stream:out" /> </route> <route> <from uri="direct:b" /> <setBody> <constant>Endpoint Direct b</constant> </setBody> <to uri="stream:out" /> </route> <route> <from uri="direct:c" /> <setBody> <constant>Endpoint Direct c</constant> </setBody> <to uri="stream:out" /> </route> </camelContext> </beans>
CamelLoadBalanceRoundRobinUsingSpring:
package com.javarticles.camel; import org.apache.camel.CamelContext; import org.apache.camel.spring.SpringCamelContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class CamelLoadBalanceRoundRobinUsingSpring { public static final void main(String[] args) throws Exception { ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext( "loadBalancingRoundRobinCamelContext.xml"); CamelContext camelContext = SpringCamelContext.springCamelContext( appContext, false); try { camelContext.start(); Thread.sleep(5000); } finally { camelContext.stop(); appContext.close(); } } }
Output:
Endpoint Direct a Endpoint Direct b Endpoint Direct c Endpoint Direct a Endpoint Direct b
Download the source code
This was an example about Apache Camel’s Load Balancer.