Wednesday, July 30, 2008

How to load balance Tomcat 5.5 with Apache on Windows



It's rather amazing that I could not find a single how-to that could detail the steps for using the Apache web server to load balance multiple Tomcat 5.5 instances on Windows. I found tons of articles- but they were either for older versions of Tomcat or Apache or for Unix flavors and none were accurate enough. Apache itself has fragmented documentation on the subject, and after much trial and error and pulling of hair, I succeeded.

The least I can do is list the steps here for all others who have had trouble getting it right.
The goal of this blog is to set up two Tomcat 5.5 instances with Apache in front, load balancing them. Please note that this does not cover clustering. I'll save that for another blog once I actually do it :-)
Also, this is not a tutorial on load balancing. It will get you up and running- then you might want to look at the Tomcat documentation to find out what exactly all those options do.

So, this is what you need to download:
1. Apache HTTP server 2.2.4 from The Apache HTTP Server Project. I prefer the zip over the Windows Installer. You are free to choose the Windows Installer if you wish, but modify the service instructions below accordingly.

2. Apache Tomcat 5.5.20 from Apache Tomcat downloads

3. Mod JK Tomcat connector from here. Please note: You want to download the binary- click on JK 1.2 Binary Releases --> win32 --> jk-1.2.21 --> mod_jk-apache-2.2.4.so

Now let's start by installing Tomcat first.

1. Extract the Tomcat zip. Hereafter, the directory you extracted to will be referred to as TOMCAT_HOME

2. Test Tomcat to see that it works. Go to TOMCAT_HOME\bin and run startup.bat
You may need to add an environment variable called CATALINA_HOME which is set to TOMCAT_HOME in case Tomcat fails to start.

3. Open up your browser and access http://localhost:8080/
If you see the default page, then Tomcat Instance 1 is working fine. Shut down Tomcat.

4. Now set this up as a service. Go to your command prompt, change directory to TOMCAT_HOME\bin and set an environment variable called CATALINA_BASE. The value of this variable should again, be TOMCAT_HOME. For example:

SET CATALINA_BASE=C:\Tomcat-5.5.20

Then, execute the following: service install Tomcat5
This will set up the Windows service for Tomcat.

5. Go to your Services and see that Tomcat 5 is listed. Start the service, and then verify again that http://localhost:8080 is up.
That's all for the first Tomcat instance. Now for the second.

1. Make a directory called SecondInstance in TOMCAT_HOME

2. Copy the conf, logs, shared, temp, webapps and work directories from the TOMCAT_HOME directory into the SecondInstance directory.

3. Open up SecondInstance\conf\server.xml in a text editor. We've got to change the port numbers so that they don't conflict with the first instance.
I just incremented by 10 and changed them as follows, but you could use other port numbers:

to

to


to

Change the SSL port if you need it as well.


4. Now set up the second instance to run as a service. Go to the command prompt, change to the TOMCAT_HOME\bin directory. Set the CATALINA_BASE environment variable to TOMCAT_HOME\SecondInstance. For example:

SET CATALINA_BASE=C:\Tomcat5.5.20\SecondInstance
Then, type:
service install SecondTomcat

Go to Services and start the SecondTomcat service. Test it out by pointing your browser to http://localhost:8090/
Works ok? Great! Your second tomcat instance is now ready to be used.

Next, let's set up the Apache HTTP Server. It's pretty simple...

1. Run the installer you downloaded. The standard install will do.

2. Open the Apache Server Monitor and start the web server if it's not already running.

3. Point your browser to http://localhost/ to verify that Apache is running on port 80.

4. Stop Apache.

Finally, we reach mod JK. Let's set it up first just to delegate requests to the two Tomcat instances, and we'll load balance it a bit later.

1. Copy the mod_jk-apache-2.2.4.so to the modules directory in your Apache installation.

2. Rename it to mod_jk.so

3. Open up httpd.conf in the conf directory of your Apache installation in a text edit, and add the following line at the end of the set of LoadModule statements:
LoadModule jk_module modules/mod_jk.so

4. Create a file called workers.properies in the conf directory. Add these lines to it:


workers.tomcat_home=C:/tomcat-5.5.20

workers.java_home=C:/jdk1.5.0_03

worker.list=worker1,worker2

worker.worker1.port=8009
worker.worker1.host=localhost
worker.worker1.type=ajp13

worker.worker2.port=8019
worker.worker2.host=localhost

worker.worker2.type=ajp13


This file defines which workers Apache can delegate to. We've listed worker1 and worker 2 to correspond to our two tomcat instances. Remember to set tomcat_home and java_home as well.

5. Specify the worker properties in httpd.conf:

Add these lines just after the LoadModule definitions-

# Path to workers.properties
JkWorkersFile c:/apache2.2/conf/workers.properties

# Path to jk logs
JkLogFile c:/apache2.2/mod_jk.log

# Jk log level [debug/error/info]
JkLogLevel info

# Jk log format
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "

# JkOptions for forwarding
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories

# JkRequestLogFormat set the request format
JkRequestLogFormat "%w %V %T"


JkMount /jsp-examples worker1
JkMount /jsp-examples/* worker1

JkMount /tomcat-docs worker2
JkMount /tomcat-docs/* worker2

Defining these tells Apache where to look for definitions of its workers and tells it that any requests for the jsp-examples context should be handed off to the Tomcat instance represented by worker 1, and any requests for tomcat-docs context should be handed off to Tomcat Instance 2, represented by worker 2.

5.5 [Added on April 11 2007]
Edit the server.xml for Tomcat and Tomcat's SecondInstance and add a jvmRoute attribute to the Engine element:

for the first instance and

for the second.

6. Start Tomcat Instance 1 and 2. Start up the Apache webserver. Point your browser to http://localhost/jsp-examples/ and then to http://localhost/tomcat-docs. You should see the respective pages load. To distinguish which Tomcat is serving you the page, the easiest thing to do is edit the index page in the tomcat-docs and jsp-examples of Tomcat 2 and change the title for example. Then you can verify that tomcat-docs is being served only by the second instance.

Thats it!! Apache is now delegating requests to both Tomcats.
Now for our last task- we will load balance it so that Apache distributes load for jsp-examples between both instances of Tomcat. It also serves as a failover mechanism. If Tomcat 1 is down for whatever reason, Apache will automatically keep delegating to Tomcat 2 so your application remains accessible.

Load balancing is a simple configuration. First shut down your Tomcat instances and Apache as well.

1. Open workers.properties in a text editor.

2. Edit it so it looks like this (changed lines in bold)-

workers.tomcat_home=C:/tomcat-5.5.20
workers.java_home=C:/jdk1.5.0_03

#worker.list=worker1,worker2
worker.list=balancer

worker.worker1.port=8009
worker.worker1.host=localhost
worker.worker1.type=ajp13
worker.worker1.lbfactor=1

worker.worker2.port=8019
worker.worker2.host=localhost
worker.worker2.type=ajp13
worker.worker2.lbfactor=1

worker.balancer.type=lb
worker.balancer.balance_workers=worker1,worker2
worker.balancer.method=B

We've changed the worker list to a single worker called balancer, and specified that the worker type of balancer is 'lb' or load balancer. The workers it manages are worker1 and worker2 (these do not need to appear in the workers list). And finally, we set the balance method to 'B' or balance by busy factor. Apache will delegate the next request to the Tomcat instance which is least busy. Please note that there are a couple of options for method- consult the Apache/Tomcat documentation which lists out options for workers properties to help you decide the best method for your type of application.

3. Open httpd.conf and comment out the previous JkMount directives. Replace them with these:

JkMount /jsp-examples balancer
JkMount /jsp-examples/* balancer

Very simple- we've just pointed Apache to a single worker- the balancer.

4. Start up both Tomcats and Apache. Access http://localhost/jsp-examples
You will either be served by Tomcat 1 or Tomcat 2. To prove that both are capable of serving, shut down the first instance and refresh your browser. You should be served by instance two.

Congratulations! You've successfully set up Apache load balancing multiple tomcat instances!

SOURCE:- thought-bytes.blogspot.com

3 comments:

Samuel said...

Excellent article, as a continuation of this article you might be interested in:

http://wiki.jboss.org/wiki/OptimalMod_jk1.2Configuration

which covers tuning mod_jk.

Jerry Stephen said...

Excellent!..

Alexey said...

Tomcat config examples are void (stripped out by Blogger) - you need show XML elements as code snippets.