Load balancing is a common issue for many web-sites or web-based applications. Last couple weeks I had to play around with a Java-based web application that, among other things, needed to be balanced for high availability and failover. The most handy solution for this seemed to be Apache httpd and mod_jk. I won’t get into the details about setting up and configuring this stuff as it can be read on hundreds of other websites. What I want to show you is a simple way to get a more realistic (even if not bullet-proof) load balancing configuration out of this.
Let’s take a sample mod_jk configuration of a load balancer with 2 nodes. This configuration also includes a jkstatus worker that we use to monitor the overall status of mod_jk.
JkMount /test/* router
JkMount /jkstatus/* jkstatus
...
JkWorkerProperty worker.list=router, jkstatus
JkWorkerProperty worker.worker1.host=localhost
JkWorkerProperty worker.worker1.port=8009
JkWorkerProperty worker.worker1.type=ajp13
JkWorkerProperty worker.worker1.lbfactor=1
...
JkWorkerProperty worker.worker2.host=localhost
JkWorkerProperty worker.worker2.port=8019
JkWorkerProperty worker.worker2.type=ajp13
JkWorkerProperty worker.worker2.lbfactor=1
...
JkWorkerProperty worker.router.type=lb
JkWorkerProperty worker.router.balance_workers=worker1, worker2
...
JkWorkerProperty worker.jkstatus.type=status
As you can see, the lbfactor must be set here manually and I used 1 for both nodes to create an equally balanced cluster. The problem that we encountered is that we need to set the lbfactor at runtime based on the actual load of the Tomcat nodes. For example, we might want the load factor to indicate the CPU usage or memory allocation percentage.
Using the jkstatus worker, there is a very simple way to do this, once you obtained your number that indicates the load factor of your node. Assuming that the gateway (the machine running the Apache with mod_jk) is accessible from the machines running Tomcat, we can use wget to easily set the load factor:
wget "http://gateway_ip/jkstatus/?cmd=update&from=list&w=router&sw=worker1&wf=453"
Once you did this, your value (453) can be seen in the corresponding row for worker1 on the page located at http://gateway_ip/jkstatus/.
This might not be the most enterprisey way to do this stuff, but it’s a quick solution that can provide a pretty realistic load balancing (as long as the factor itself is calculated in a realistic manner).
You can put this stuff in a script, for example an update_lbfactor.sh on a shared NFS drive and adjust it to accept the worker and the load factor as arguments:
wget "http://gateway_ip/jkstatus/?cmd=update&from=list&w=router&sw=$1&wf=$2"
This way, the nodes will just have to call this with the appropiate arguments:
update_lbfactor.sh worker2 345
Hope you find this usefull.