DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
View Events Video Library
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Integrating PostgreSQL Databases with ANF: Join this workshop to learn how to create a PostgreSQL server using Instaclustr’s managed service

Mobile Database Essentials: Assess data needs, storage requirements, and more when leveraging databases for cloud and edge applications.

Monitoring and Observability for LLMs: Datadog and Google Cloud discuss how to achieve optimal AI model performance.

Automated Testing: The latest on architecture, TDD, and the benefits of AI and low-code tools.

Related

  • AWS Web Application and DDoS Resiliency
  • How To Implement and Design Twitter Search Backend Systems using Java Microservices?
  • Load-Balancing Minecraft Servers with Kong Gateway
  • Conciliate the Tangled Mesh Using ISTIO

Trending

  • What Is Good Database Design?
  • Vector Database: A Beginner's Guide
  • The Promise of Personal Data for Better Living
  • Understanding Git
  1. DZone
  2. Coding
  3. Frameworks
  4. How to Load Balance RESTful Web Services Using CXF and Apache Camel

How to Load Balance RESTful Web Services Using CXF and Apache Camel

This article shows you two approaches to load balance JAXRS web services without an Apache or a hardware load balancer.

Milan Sonkar user avatar by
Milan Sonkar
·
Jun. 17, 16 · Tutorial
Like (8)
Save
Tweet
Share
10.17K Views

Join the DZone community and get the full member experience.

Join For Free

In this article I am going to show you two approaches to load balance JAXRS web services without an Apache or a hardware load balancer. The full code is available on GitHub. CXF provides clustering strategies which can be used for configuring a load balancer which has already been discussed here. However, load balancing the JAXRS requires a little more effort, which I have described in this article.

Below are the two approaches to load balance JAXRS services using CXF and Apache Camel.

1. Using CXF Clustering With Apache Camel

In this approach, we leverage the CXF clustering and Camel to load balance the JAXRS web service. Following are the components used for achieving the load balancing:

  •  Proxy JAXRS Service

<cxf:rsServer id="LBRSServer" address="/rest"
serviceClass="com.milan.cxf.jaxrs.PersonLBService">
    <cxf:providers>
        <beans:bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider" />
        <beans:bean
class="com.milan.cxf.jaxrs.exception.ApplicationExceptionMapper" />
        <beans:bean class="com.milan.cxf.jaxrs.exception.GenericExceptionMapper" />
    </cxf:providers>
</cxf:rsServer>

This JAXRS service serves as the proxy for actual JAXRS service implementation which is hosted on multiple servers.

  •  JAXRS Client

<cxf:rsClient id="personRSServiceClient" address="/xyz"
serviceClass="com.milan.cxf.jaxrs.client.PersonRSServiceClient"
inheritHeaders="true">
    <cxf:features>
        <clustering:loadDistributor>
            <clustering:strategy>
                <beans:ref bean="sequentialStrategy" />
            </clustering:strategy>
        </clustering:loadDistributor>
    </cxf:features>
    <cxf:headers>
        <beans:entry key="Accept" value="text/xml" />
    </cxf:headers>
</cxf:rsClient>

This is a simple JAXRS client using CXF clustering feature to load balance the two servers hosting the actual JAXRS service. This can be used with Sequential or RandomStrategy to schedule the calling pattern of the two servers.Here I have used sequentialStrategy for load balancing as detailed below:

<util:list id="addressList" value-type="java.lang.String">
    <beans:value>${server1}</beans:value>
    <beans:value>${server2}</beans:value>
</util:list>
<beans:bean id="sequentialStrategy"
class="org.apache.cxf.clustering.SequentialStrategy">
    <beans:property name="alternateAddresses">
        <beans:ref bean="addressList" />
    </beans:property>
</beans:bean>

The number of servers in the addressList can be anything. In the above code, this server list is coming from config.properties file as shown below:

server1 = http://localhost:8080/CXFRS/services/rest
server2 = http://localhost:8081/CXFRS/services/rest
  • Camel Route

public class CXFLBRoute extends RouteBuilder{

    @Override
    public void configure() throws Exception
    {
        from("cxfrs:bean:LBRSServer").routeId("CXFLBRoute").autoStartup(true).log("${body}").to("cxfrs:bean:personRSServiceClient");
    }
}

This is a simple camel route which takes the request from the proxy JAXRS service and passes the message to JAXRS client which calls either of the hosted JAXRS service in the addressList based on the scheduling strategy.

2.Using Apache Camel Load Balancer Pattern

  •  Proxy JAXRS service

<cxf:rsServer id="LBRSServer" address="/rest"
serviceClass="com.milan.cxf.jaxrs.PersonLBService">
    <cxf:providers>
        <beans:bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider" />
        <beans:bean
            class="com.milan.cxf.jaxrs.exception.ApplicationExceptionMapper" />
        <beans:bean class="com.milan.cxf.jaxrs.exception.GenericExceptionMapper" />
    </cxf:providers>
</cxf:rsServer>

This JAXRS service serves as the proxy server for actual JAXRS service which is hosted on multiple servers. This is same as in Approach 1.

  •  Camel Route Using Load Balancer Pattern

public class CamelLoadBalancerRoute extends RouteBuilder{

    @Override
    public void configure() throws Exception
    {
        from("cxfrs:bean:LBRSServer").routeId("CamelLBRoute").autoStartup(true).log("${body}").process(new Processor(){
            public void process(Exchange exchange)
            {
                Map<String,Object> headerMap = exchange.getIn().getHeaders();
                String camelHttpPath = headerMap.get("CamelHttpPath").toString();
                Message message = exchange.getOut();
                message.setHeader(Exchange.HTTP_PATH, camelHttpPath);
            }
        }).convertBodyTo(InputStream.class)
    .loadBalance().roundRobin().to("{{server1}}","{{server2}}");
    }
}

This is a simple camel route which takes the request from the proxy JAXRS service, converts the body to InputStream and passes the message to one of the servers in the load balancer list. The server list is being populated into Camel PropertiesComponent in the applicationContext.xml as detailed below:

<beans:bean id="properties"
    class="org.apache.camel.component.properties.PropertiesComponent">
    <beans:property name="location"
        value="classpath:/config/config.properties" />
</beans:bean>

Using any of the above two approaches gives us a simple REST URL which we can hit and get a response directly hiding the load balancer implementation completely. Both the approaches can be used for Failover and Circuit Breaker configurations as well.

The code comprises of two Gradle projects:

1. CXLB: This is a load balancer application.This needs to be deployed on one of the nodes in our cluster. Update the con/config.xml file with the JAXRS server list where CXFRS is deployed to make it function correctly.

2. CXFRS: JAXRS web service code. This needs to be deployed on as many nodes as we want in our cluster.

We just need to do Gradle clean build the two projects and deploy the wars on different servers.

Try load-balancing JAXRS web services using this example!

Web Service Apache Camel Load balancing (computing)

Opinions expressed by DZone contributors are their own.

Related

  • AWS Web Application and DDoS Resiliency
  • How To Implement and Design Twitter Search Backend Systems using Java Microservices?
  • Load-Balancing Minecraft Servers with Kong Gateway
  • Conciliate the Tangled Mesh Using ISTIO

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: