Thursday, January 12, 2012

HTTP load balancing using Apache and Mod_jk


Environment
J2EE Application deployed in JBOSS AS 5. Same such Jboss instances are clustered. If we need to load balance the HTTP requests across the various jboss instances the following steps can be followed. This post basically depicts the configurations done to setup a HTTP load balancer.

Software Packages Required

  • Apache 2.2.x
  • mod_jk 1.2.x

Apache server can be downloaded directly from Apache web site at http://httpd.apache.org/.

The mod_jk 1.2.x binary can be downloaded from http://www.apache.org/dist/jakarta/tomcat-connectors/jk/binaries/. Rename the downloaded file to mod_jk.so and copy it under APACHE_HOME/modules/.

Configure Apache to load mod_jk
Step1. Modify APACHE_HOME/conf/httpd.conf and add a single line at the end of the file:
# Include mod_jk's specific configuration file  
Include conf/mod-jk.conf
Step2. Create a new file named APACHE_HOME/conf/mod-jk.conf:
# Load mod_jk module
# Specify the filename of the mod_jk lib
LoadModule jk_module modules/mod_jk.so
 
# Where to find workers.properties
JkWorkersFile conf/workers.properties

# Where to put jk logs
JkLogFile logs/mod_jk.log
 
# Set the jk log level [debug/error/info]
JkLogLevel info 
 
# Select the log format
JkLogStampFormat  "[%a %b %d %H:%M:%S %Y]"
               
# Mount your applications
JkMount /application/* loadbalancer
 
Configure worker nodes in mod_jk
The mod_jk workers file conf/workers.properties should be configured. This file specifies where the different Servlet containers are located and how calls should be load-balanced across them. The configuration file contains one section for each target servlet container and one global section. For a two nodes setup, the file could look like this:

# Define list of workers that will be used
# for mapping requests
worker.list=loadbalancer,status

# Define Node1
# modify the host as your host IP or DNS name.
worker.node1.port=8009
worker.node1.host=192.168.2.50
worker.node1.type=ajp13
worker.node1.lbfactor=1
worker.node1.cachesize=10

# Define Node2
# modify the host as your host IP or DNS name.
worker.node2.port=8009
worker.node2.host= 192.168.2.52
worker.node2.type=ajp13
worker.node2.lbfactor=1
worker.node2.cachesize=10

# Load-balancing behaviour
worker.loadbalancer.type=lb
worker.loadbalancer.balance_workers=node1,node2
worker.loadbalancer.sticky_session=1
#worker.list=loadbalancer


# Status worker for managing load balancer

worker.status.type=status

Sticky Session
The sticky_session property specifies the cluster behavior for HTTP sessions. If worker.loadbalancer.sticky_session=0, each request will be load balanced between node1 and node2; i.e., different requests for the same session will go to different servers. But when a user opens a session on one server, it is always necessary to always forward this user's requests to the same server, as long as that server is available. This is called a "sticky session", as the client is always using the same server he reached on his first request. To enable session stickiness, you need to set worker.loadbalancer.sticky_session to 1.

Lbfactor
The lbfactor attribute is the load-balancing factor for a specific worker. It is used to define the priority (or weight) a node should have over other nodes. The higher this number is for a given worker relative to the other workers, the more HTTP requests the worker will receive. This setting can be used to differentiate servers with different processing power.


Configuring JBoss to work with mod_jk

On each clustered JBoss node, we have to name the node according to the name specified in workers.properties. For instance, on JBoss instance node1, edit the JBOSS_HOME/server/all/deploy/jbossweb.sar/server.xml file Locate the <Engine> element and add an attribute jvmRoute:


<Engine name="jboss.web" defaultHost="localhost" jvmRoute="node1">
... ...
</Engine>