C2B2 logo icon

How to Configure JBoss EAP 7 as a Load Balancer

Brian returns to the new features now available to JBoss administrators in EAP 7, and looks specifically at configuring Undertow as an http load balancer.

In Brian's recent First Look at EAP 7, he identified the implementation of Undertow as a direct replacement for JBoss Web as one of the key changes from EAP 6. In this post, he demonstrates how to configure Undertow as an http load balancer.
 

Environment

The environment I used was an Amazon EC2 t2.medium tier shared host running Red Hat Linux 7.2 (Maipo) with 4GB Ram and 2vCPUs. This has Oracle Java JDK 8u92 and JBoss EAP 7.0.0 installed.
 
I wanted to have three separate standalone servers, so I copied the standalone folder three times from the vanilla EAP 7 install and renamed them standalone-lb, standalone-server1, standalone-server2.
 
I then ran three instances of JBoss, using the -Djboss.server.base.dir command line argument for each one to specify the three different configurations. I kept the lb server with the default ports but used the port offset argument -Djboss.socket.binding.port-offset to offset the ports by 100 for each server.
 
Hence, for http the lb was running on port 8080 and server1 and server2 were running on ports 8180 and 8280 respectively.
 

Application

Next I needed to find a web application to run on JBoss - one that would show me that the load balancing had pointed to that server.
 
I decided to use the JBoss EAP 7 Quickstart for helloworld-html5. This provides a very simple page in which you can add your name, press a button and...hey presto, your name will be displayed. What it also does is provide a stdout message in the logs with the name you have entered - hence it is easy to know which server you have connected to.
 
I imported the helloworld-html5 project into JBoss Developer Studio and exported the war file which I then deployed onto server1 and server2.
 
Testing it on server 2 (with port offset of 200) using the URL http://:8280/helloworld-html5/ you can see the message displayed on the screen and the name entered in the log file:

 
 

Configuring

So now we need to configure the load balancing on the lb server.

 
For this, we need to add some configuration to Undertow to reference the outbound destinations that we also need to configure for our servers. For this, we will be :
 
  • Adding in remote outbound destinations for the servers we want to load balance (providing the hostname and port)
  • Adding a reverse proxy handler into Undertow
  • Adding the outbound destinations to the reverse proxy handler (setting up the scheme we want to use, i.e. ajp or http, and the path for the application which in our case is helloworld-html5)
  • Adding the Reverse Proxy location (i.e. what url path will we follow on the Load Balancer for it to be redirected)

The following CLI configured the outbound destinations:

/socket-binding-group==standard-sockets/remote-destination-outbound-socket-binding=lbhost1/:add(host=10.0.0.55, port=8180)
/socket-binding-group==standard-sockets/remote-destination-outbound-socket-binding=lbhost2/:add(host=10.0.0.55, port=8280)
You can see these now configured in the console :

You can see these now configured in the console :

 

The following CLI added the reverse proxy handler (I have called it ‘lb-handler’) to Undertow:
/subsystem=undertow/configuration=handler/reverse-proxy=lb-handler:add

The following CLI adds the remote destinations to the reverse proxy handler (I have named the hosts ‘lb1’ and ‘lb2’ and have named the instance-id ‘lbroute’ for both so it will round robin around them):

/subsystem=undertow/configuration=handler/reverse-proxy=lb-handler/host=lb1:add(outbound-socket-binding=lbhost1, scheme=http, instance-id=lbroute, path=/helloworld-html5)
/subsystem=undertow/configuration=handler/reverse-proxy=lb-handler/host=lb2:add(outbound-socket-binding=lbhost2, scheme=http, instance-id=lbroute, path=/helloworld-html5)

We can now see the completed handler configuration:

/subsystem=undertow/configuration=handler/reverse-proxy=lb-handler:read-resource(recursive=true)
{
    "outcome" => "success",
    "result" => {
        "cached-connections-per-thread" => 5,
        "connection-idle-timeout" => 60L,
        "connections-per-thread" => 10,
        "max-request-time" => -1,
        "problem-server-retry" => 30,
        "request-queue-size" => 10,
        "session-cookie-names" => "JSESSIONID",
        "host" => {
            "lb1" => {
                "instance-id" => "lbroute",
                "outbound-socket-binding" => "lbhost1",
                "path" => "/helloworld-html5",
                "scheme" => "http",
                "security-realm" => undefined
            },
            "lb2" => {
                "instance-id" => "lbroute",
                "outbound-socket-binding" => "lbhost2",
                "path" => "/helloworld-html5",
                "scheme" => "http",
                "security-realm" => undefined
            }
        }
    }
}

And to complete the configuration I add the location which the handler will handle with the following CLI (setting this so that anything going to the /app URL will be handled)

/subsystem=undertow/server=default-server/host=default-host/location=/app:add(handler=lb-handler)

This we can now see in the settings

/subsystem=undertow/server=default-server/host=default-host/location=\/app:read-resource(recursive=true)
{
    "outcome" => "success",
    "result" => {
        "handler" => "lb-handler",
        "filter-ref" => undefined
    }
}

That is all the configuration we need.

Testing

To test we use the URL on the LoadBalancer with /app, this should now redirect to the remote servers using /helloworld-html5. If I then type in a value and press the button I can see which server I have been redirected to.

We can see when tailing the logs on both the servers that I can refresh the browser which redirects to the other server and it continues in a round robin pattern.
 
 

Summary

There you go - a straight-forward process to configure JBoss EAP 7 standalone mode as a http load balancer in front of two standalone servers using round robin.