Apache Camel failover load balancer with dynamic endpoints
#Table of Contents
#Introduction
This post showcases how to create an Apache Camel route, which load balances a dynamic number of endpoints. The load balancer will use the Round Robin algorithm, and it will be paired with failover in order to achieve high availability.
#Failover
As stated already, the endpoints need to be dynamic, i.e. configurable. The Apache Camel Failover documentation thoroughly explains how to create a failover load balancer, but with static endpoints that are defined directly inside the code.
In order to have dynamic endpoints, the route definition that is demonstrated in the documentation needs to be modified a bit.
Note: The following is a small demonstration. In the next section a complete example is shown.
Original:
from("direct:start")
.loadBalance().failover(10, false, true)
.to("http:service1")
.to("http:service2")
.to("http:service3")
.end();
Modified:
LoadBalanceDefinition route = from("direct:start")
.loadBalance()
// Failover at most 10 times in round-robin mode
.failover(10, false, true);
// The endpoints should ideally be configured in the `application.properties` or `application.yaml`
// String[] endpoints = { "http:service1", "http:service2", "http:service3" };
for (String endpoint : endpoints) {
route = route.to(endpoint.trim() + "?bridgeEndpoint=true");
}
route.end();
#Code
#application.properties
example.endpoints="http://example-one.com/foo","http://example-two.com/bar"
#Class
@Component
public class ExampleRoute extends RouteBuilder {
@Value("${example.endpoints}")
private String[] exampleEndpoints;
@Override
public void configure() {
final String exampleRouteId = "example-route";
final String exampleRoute = "direct:" + exampleRouteId;
rest("/example")
.get()
.to(exampleRoute);
LoadBalanceDefinition route = from(exampleRoute)
.routeId(exampleRouteId)
.loadBalance()
// Continuously try to failover in round-robin mode
.failover(-1, false, true);
for (String endpoint : exampleEndpoints) {
route = route.to(endpoint.trim() + "?bridgeEndpoint=true");
}
route.end();
}
}
#Conclusion
Turns out this was fairly easy, but I wish I had this kind of resource when working with Apache Camel. Wasted more time than I’d like to admit. One skill issue at a time…