Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

I want to use apache load balancer so that one tomcat server is primary, and the secondary server is online only if the first server is down. how can this be done?

share|improve this question
    
Are you using mod_jk on the apache server? If not, you might want to look into a more lightweight solution like HAproxy –  Matt Simmons Jan 30 '11 at 18:49
    
how do i find out if I use mod_jk? –  user12145 Jan 30 '11 at 19:32
    
If you don't know, there's a good chance that you aren't. –  Matt Simmons Jan 30 '11 at 19:43

2 Answers 2

up vote 8 down vote accepted

If you're only going to do load balancing, I would recommend something more lightweight than Apache, such as HAproxy, but lets assume that you're going to go with apache.

There are several methods for load balancing, so you should spend a little bit of time getting acquainted with them. There is an excellent article available by Willy Tarreau called Making applications scalable with Load Balancing that is worth your time to read.

There are a couple of tools for making Apache a load balancer, and maybe the easiest (that I know of) is by using mod_proxy_balancer. The only problem with this is that it doesn't appear to do failover load balancing (which is what you want: high availability, rather than true load balancing).

Since you're using Tomcat, why not use mod_jk, the Apache tomcat connectors?

Assume for a second that we're on a Redhat-based system (I'm using CentOS 5.5) that is configured to compile things (for instance, has gcc and the appropriate libraries (this isn't a good idea on production systems. This is not the time or place to discuss RPM packaging, though)

 yum install httpd httpd-devel

This will install Apache along with the development stuff for making modules, and the configuration directory will be /etc/httpd/

The current (20110130) Tomcat Connectors are 1.2.31 (but you can check for the latest here), so download them:

 wget http://mirror.cc.columbia.edu/pub/software/apache//tomcat/tomcat-connectors/jk/source/jk-1.2.31/tomcat-connectors-1.2.31-src.tar.gz

Extract, compile, and install them:

 tar zxvf tomcat-connectors-1.2.31-src.tar.gz 
 cd tomcat-connectors-1.2.31-src/native
 ./configure --with-apxs=/usr/sbin/apxs 
 make 
 sudo make install 

Verify that mod_jk.so was installed:

 ls -al /etc/httpd/modules/mod_jk.so 
 -rwxr-xr-x 1 root root 903072 Jan 30 15:21 /etc/httpd/modules/mod_jk.so

Now, we get to actually configure it.

Edit /etc/httpd/conf.d/jk.conf:

 # This actually tells apache to load the module we built
 LoadModule jk_module modules/mod_jk.so 

 # This file holds the instructions for which servers the proxy will be talking to
 JKWorkersFile /etc/httpd/conf.d/workers.properties

 # This is (obviously) the logfile that it will write to. Change to whatever you want
 JKLogFile /var/log/httpd/mod_jk.log 

 # Simplistically, we'll set up a virtualhost that listens on all IPs on port 80. 
 # HTTPS is left as an exercise for the reader
 NameVirtualHost *:80
 <VirtualHost *:80>
     ServerAdmin you@yourdomain.com 
     ServerName thedomainnameoftheproxy.com

     # The following line says "send anything to the JK Worker named MyProxyCluster"
     JKMount /* MyProxyCluster

 </VirtualHost>
 #EOF

Alright, that tells Apache that we want to use mod_jk, that we want to use a file called /etc/httpd/conf.d/workers.properties, and that we have one virtualhost where everything is sent to the workers. Great, now lets configure the workers. Edit /etc/httpd/conf.d/workers.properties:

 # We're telling mod_jk which workers it needs to look for. We're going to define 
 # a total of 3 workers: MyProxyCluster (the load balancer job), worker1, and worker2 
 # (the two backend servers) 
 worker.list=MyProxyCluster

 worker.worker1.port=8009
 worker.worker1.host=hostname.or.ip.of.1st.tomcat.server

 # ajp13 means Apache JServ Protocol version 1.3, and is apparently universal
 worker.worker1.type=ajp13

 worker.worker1.lbfactor=1

 # When worker1 dies, we're going to want it to go to worker2
 worker.worker1.redirect=worker2

 ### End of worker1 config

 # repeat the same things for worker2
 worker.worker2.port=8009
 worker.worker2.host=hostname.of.ip.of.2nd.tomcat.server
 worker.worker2.type=ajp13
 worker.worker2.lbfactor=1
 # Disable worker2 except when it fails over
 worker.worker2.activation=disabled

 # make the actual load balancer worker that we referenced in the beginning
 worker.MyProxyCluster.type=lb
 worker.MyProxyCluster.balance_workers=worker1,worker2
 # EOF

Now, we have two actual workers, and one virtual load balancer for them. You can now start Apache:

 service httpd start 

Test it out by browsing to the machine, and it should go to the first tomcat server. You should be able to verify this by watching /var/log/httpd/mod_jk.log (or wherever you pointed it).

Good luck!

share|improve this answer

Here is a much simpler solution using AJP instead of JK:

<Proxy balancer://cluster>
    BalancerMember ajp://127.0.0.1:8009 route=jvm1 status=-D
    BalancerMember ajp://127.0.0.2:8009 route=jvm2 status=+H
</Proxy>

ProxyPass /app balancer://cluster/app

There are quite a few more configuration properties you can set, such as differential load factors if you have more backends, different balancing algorithms, balancer sets, etc: see the Apache mod_proxy documentation, but the above does exactly what you specified. -D means 'not disabled' and +H means 'hot standby'. And you can swap them at runtime too.

You just need to run two Tomcats, with AJP connectors running on port 8009 with address="127.0.0.1", address="127.0.0.2" etc, as many as you need, with <Engine jvmRoute="jvm1"> and <Engine jvmRoute="jvm2"> respectively. Note the economy of ports: you can do the same with the shutdown port too. Throw away anything in the Tomcat configuration referring to JK, mod_jk, etc. You don't need those frightful workers.properties files either. You can also throw away all the HTTP and HTTPS connectors and terminate inbound SSL at the Apache HTTPD, which gives you much finer-grained control over SSL.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.