Tomcat High Availability & Clustering
Tomcat servers need to be clustered. This requirement is for constant uptime.
The following solution brings up 2 Tomcat servers and one Apache server. The customer web-sites will contact the Apache web server. The Apache web server will divert the traffic to a Tomcat server.
Here I describe the method and some reference web pages:
1. Install 2 copies of Tomcat server, on the same host or different hosts, depending on your requirements. Here I have given the example of installing on the same host. I named the servers tomcat1 and tomcat2.
2. Open server.xml files for tomcat1 and tomcat2. Change the following line in tomcat1/conf/server.xml to:
<Connector port="8091" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true" />
3. Change the following line in tomcat2/conf/server.xml to:
<Connector port="8092" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true" />
4. Also on the second server, change the port in the server entry at the top. For example:
<Server port="8006" shutdown="SHUTDOWN">
5. Download sources of mod_jk from the following URL:
http://tomcat.apache.org/connectors-doc/
Build mod_jk. If required download the following rpms:
apr-devel-1.2.7-10.i386.rpm
apr-util-devel-1.2.7-3.i386.rpm
6. Modify Apache’s httpd.conf to add following line:
LoadModule jk_module modules/mod_jk.so
7. Edit the workers.properties file inside tomcat1/conf directory.
Set workers.tomcat_home=<tomcat installation directory>
This is where the conf files are. This has to be set only once.
8. Set workers.java_home=/usr/java/jdk1.5.0_10
This is the Java Home directory.
9. Set worker.list=tomcat1, tomcat2, loadbalancer
Think of loadbalancer as the root node for tomcat1 and tomcat2 as worker nodes.
10. Set the following properties for the first worker thread:
worker.tomcat1.port=8009
worker.tomcat1.host=192.168.1.101
worker.tomcat1.type=ajp13
worker.tomcat1.lbfactor=1
Note that the port is the AJP port, not the default tomcat port.
11. Set the following properties for the second worker thread:
worker.tomcat2.port=8010
worker.tomcat2.host=192.168.1.101
worker.tomcat2.type=ajp13
worker.tomcat2.connection_pool_timeout=600
worker.tomcat2.socket_keepalive=1
worker.tomcat2.socket_timeout=60
worker.tomcat2.lbfactor=1
Note that the port is the AJP port, not the default tomcat port.
12. Set the following properties for the loadbalancer thread:
worker.loadbalancer.type=lb
worker.loadbalancer.balance_workers=tomcat1, tomcat2
13. Set the following properties for the status thread:
# Add the status worker to the worker list
worker.list=jkstatus
# Define a 'jkstatus' worker using status
worker.jkstatus.type=status
14. Edit the Apache’s httpd.conf file and add the following lines:
# JkWorkersFile must be full pathname of the file you created above
# in my case it was tomcat1/conf/workers.properties
JkWorkersFile workers.properties
# LogLevel could be info, error, debug etc. debug seems to work best
JkLogLevel debug
JkLogFile /etc/httpd/logs/mod_jk.log
# Pathname of the redirection
# This means localhost/servlets-examples/* will go to tomcat[12]
JkMount /servlets-examples/* loadbalancer
# Add the jkstatus mount point
JkMount /jkmanager/* jkstatus
JkMountCopy off
15. Having configured Apache as our dispatcher, we now need to configure the Tomcat workers.
Make sure the following line is uncommented in your tomcat1/conf/server.xml file:
<Connector port="8009"
enableLookups="false" redirectPort="8443" protocol="AJP/1.3" />
Make sure the following line is uncommented in your tomcat2/conf/server.xml file:
<Connector port="8010"
enableLookups="false" redirectPort="8443" protocol="AJP/1.3" />
16. Edit the Engine entry to have a jvmRoute matching the tomcatId entry in workers.properties:
For tomcat1/conf/server.xml file:
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">
For tomcat2/conf/server.xml file:
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat2">
17. Identify Tomcat server – create two different files called me.html inside tomcat1/webapps/servlets-examples and tomcat2/webapps/servlets-examples.
18. Make sure you restart Apache server and the Tomcat servers before you test.
Load http://host_ip_address/servlets-examples/me.html in browser. Reload it, it should load balancer between the servers.
19. For troubleshooting open /etc/httpd/logs/mod_jk.log file and try to understand what the error could be.
20. Note:
a. Set export JRE_HOME=/usr/java/jdk1.5.0_10 before you start Tomcat server.
b. To stop Tomcat, kill the Java process, don’t do shutdown, that didn’t work for me.
Phew!
References in order of relevance
1. http://www.javaworld.com/javaworld/jw-12-2004/jw-1220-tomcat.html?page=1
2. http://publib.boulder.ibm.com/iseries/v5r2/ic2924/info/rzaie/rzaiemod_jk.htm#jkworkersfile
3. http://tomcat.apache.org/connectors-doc/generic_howto/workers.html
4. http://tomcat.apache.org/connectors-doc/