Understanding Tomcat Load Balancing

On busy sites, whenever a request call is delegated from the Apache server to Tomcat, it’s a good idea to route these requests to multiple Tomcat servers rather than to a single one, which you can do with mod_jk2. mod_jk2 manages the task of load balancing with support for seamless sessions and round-robin scheduling.

Let’s first look at the concept of a seamless session (also known as session affinity or a sticky session). When a client requests any dynamic resource, such as a JSP page, for the first time, the load balancer will route this request to any of the available Tomcat instances. Now, any further request from the same browser session should be routed to the same Tomcat container instance to keep the user session alive (see Figure 9-3).

image from book
Figure 9-3: Load balancing with a Web server

If the maximum number of connections to that worker has been reached before this call, then mod_jk2 waits for the appropriate worker to become free. This is known as a seamless session because the client sees no break in the application’s function.

Here, the Tomcat instances are listening to different ports (if they’re running on the same machine) or are running on different machines. You’ll see how to configure Apache 1.3, Apache 2.0, and IIS before seeing how to configure Tomcat. The Tomcat settings are the same no matter which server you’re using, with one exception.

Preparing for Load Balancing

The first step in setting up load balancing is to designate a load-balancing (lb) worker. The load-balancing worker is responsible for managing several actual request-processing workers. The lb worker does the following:

  • Instantiates the workers in the Web server.

  • Uses the workers’ load balancing levels and load-balancing factors to perform weighted round-robin load balancing where a low level means a worker belongs to a preferred group and a low lb factor means a more powerful machine that can handle more requests than others in the group

  • Routes requests belonging to the same session to the same Tomcat worker, thus keeping session affinity

  • Identifies failed Tomcat workers, suspends requests to them, and falls back to other workers managed by the lb worker

The overall result is that workers managed by the same lb worker are load balanced (based on their lb level and factor and current user session) and covered by a fallback mechanism so that a single Tomcat process death won’t bring down the entire deployment.

The Workers

In this example, you’ll install and run different Tomcat instances on localhost. For this you have to install two different Tomcat instances on the test machine at CATALINA_HOME1, listening on port 8009, and CATALINA_HOME2, listening on port 8010. You Web server should also be running on this machine.

You should keep the following in mind:

  • Each Tomcat instance running on the same machine should listen to a unique port. However, two Tomcat instances running on two different machines (which are participating in the same load-balancing mechanism as two workers) can listen on the same port number.

  • The AJP connector of each Tomcat instance running on the same machine should listen to a unique port. However, the AJP connectors of two Tomcat instances running on two different machines (which are participating in the same load-balancing mechanism as two workers) can run on the same port.

Configuring Apache 1.3 for Load Balancing

You’ll now need to define a simple workers.properties file for the load balancing. Here, you’ll define a single worker in the worker.list option as the load-balancing worker. This worker will be the single access point for any requests delegated by Apache and will handle the other workers. Call it lb, although you can name it whatever you want.

For each Tomcat worker, define the standard parameters: the host and port on which it will be running, the load-balancing factor that should be applied, and the number of open connections accepted in the form of cache (see Listing 9-12).

Listing 9-12: A Sample workers.properties File

image from book
 # Define the path separator appropriate to the platform we are using  # For Windows Systems  ps=\  # For Linux /Unix Systems  #ps=/  # Define the load balancing worker only, and not other workers.  worker.list=lb  # ------------------------------------------------------------------------ # First Tomcat instance running on local machine (localhost)  # ------------------------------------------------------------------------ # Set the port on which it will listen  worker.tomcat1.port=8009  # Set the host on which the Tomcat worker is running   worker.tomcat1.host=localhost  # Set the type of worker, here we are using ajp13  worker.tomcat1.type=ajp13  # Specify the load-balancing factor, any value greater than 0  worker.tomcat1.lbfactor=10  # Specify the size of the open connection cache.  worker.tomcat1.cachesize=5  # ------------------------------------------------------------------------ # Second Tomcat instance running on local machine (localhost)  # ------------------------------------------------------------------------ # Set the port on which it will listen  worker.tomcat2.port=8010  # Set the host on which the Tomcat worker is running  worker.tomcat2.host=localhost  # Set the type of worker, here we are using ajp13  worker.tomcat2.type=ajp13  # Specify the load-balancing factor , any value greater than 0  worker.tomcat2.lbfactor=10  # Specify the size of the open connection cache.  worker.tomcat2.cachesize=5  # ------------------------ # Load Balancer worker  # ------------------------ worker.lb.type=lb  # State the comma-separated name of workers that will form part of this  # load balancing mechanism  worker.lb.balanced_workers=tomcat1, tomcat2 
image from book

The lb worker is of type lb and uses a weighted round-robin algorithm for load balancing with support for seamless sessions as discussed earlier. If a worker dies, the lb worker will check its state over small time intervals. Until it’s back online, all work is redirected to the other available workers.

The previous are the basic steps for integrating Tomcat and Apache, but perhaps the most important step is to tell Apache about the URL patterns that it should hand over to Tomcat, as in Listing 9-13.

Listing 9-13: Mounting the JSP Examples

image from book
 # Mappings for the requests to JSP and servlets  JkMount /tomcatBook lb  JkMount /tomcatBook/* lb 
image from book

mod_jk will forward any requests that match these patterns to the lb worker. Once the request processing is done, the response is sent to the corresponding client.

You now need to include the settings for mod_jk, the defined Tomcat lb worker, and a few other settings such as the location of the log file, the log level, and the mappings for the various resources that mod_jk will ask Tomcat to provide.

Insert the lines in Listing 9-14 at the bottom of Apache’s httpd.conf. Of course, you could use Tomcat to generate the settings for you. Remember to change the host-level listener’s jkWorker attribute to lb.

Listing 9-14: The Final Configuration for Apache

image from book
 <IfModule !mod_jk.c>    LoadModule jk_module "C:/Program Files/Apache Group/Apache/modules/mod_jk.dll"  </IfModule>  JkWorkersFile "C:/jakarta-tomcat-5.0.27/conf/workers.properties"  JkLogFile "C:/jakarta-tomcat-5.0.27/logs/mod_jk.log"  JkLogLevel info  <VirtualHost localhost>      ServerName localhost      JkMount /tomcatBook lb      JkMount /tomcatBook/* lb  </VirtualHost> 
image from book

Configuring Apache 2.0 and IIS for Load Balancing

The theory behind load balancing for Apache 2.0 and IIS is the same as for Apache 1.3, though the mechanism has been refined and of course the configuration is different. The defaults that mod_jk provides make load balancing extremely easy, as it’s set up by default. You’ll have to do a small amount of configuration on the Tomcat side, but it’s an extremely quick process.

For Apache 2.0, create a workers2.properties file in Apache 2.0’s conf directory and add the configuration shown in Listing 9-15. Do the same for IIS, but place the file in the location you specified in the registry.

Listing 9-15: A Sample workers2.properties File

image from book
 [channel.socket:localhost:8009]  tomcatId=tomcat1  [channel.socket:localhost:8010]  tomcatId=tomcat2  [ajp13:localhost:8009]  channel=channel.socket:localhost:8009  [ajp13:localhost:8010]  channel=channel.socket:localhost:8010  [status:statusWorker]  styleMode=1  [uri:/jkstatus]  group=status:statusWorker  [uri:/tomcatBook/*] 
image from book

This is almost identical to the file shown in Listing 9-9. In this case you’ve added another channel and worker listening to port 8010 on localhost. The Tomcat connector will append its name to each session identifier when it returns a response to the Web server. This allows the Web server to route subsequent responses to the appropriate Tomcat, as the client will also include this session identifier with the Tomcat name when it makes a request. You use the tomcatId attribute to identify which channel to use when a request comes in and thus implement sticky sessions. If the worker is busy, the Web server will wait until it’s ready.

Note 

Remember to generate an Apache configuration file for the tomcatBook context using the generating tools mentioned previously. Include this file in httpd.conf.

You don’t have anything else to do on the Web server side, bar the basic mod_jk2 configuration from earlier in the chapter. This is because all workers automatically belong to a load-balancing group called lb, which is governed by the lb:lb worker.

Load Balancing Level

mod_jk2 has added a fine-grained load-balancing mechanism that allows you to have more control over your workers. In mod_jk you simply had the load-balancing factor, which you could use to arrange servers in the order of ability to service requests. The higher the number, the more often a worker would receive a request from the Web server.

mod_jk2 builds on this with the concept of load-balancing levels. Load-balancing levels allow you to group workers together into load-balancing clusters, some of which are used only following a server failure. This wasn’t possible before because the load-balancing factor is a weighting that tells the Web server how often to route requests to a certain worker, which means that all workers would get a request eventually.

The load-balancing algorithm checks the lowest level first and routes requests to those workers with the lowest balancing factor. If all the workers at a certain level fail, then the algorithm moves to the next level up and assigns requests to the workers with the lowest balancing factor. This process is repeated up the chain worker failure. Therefore, workers on higher levels will be run only if all the workers on lower levels fail.

You can set the balancing factor and balancing level as attributes of a channel or a worker. Note that a worker inherits its channel’s attributes. Listing 9-16 shows an example of a load-balancing cluster.

Listing 9-16: An Example Load-Balancing Cluster

image from book
 [channel.socket:localhost:8009]  tomcatId=tomcat1  level=0  [channel.socket:server1:8009]  tomcatId=tomcat2  level=1  lb_factor=0  [channel.socket:server2:8009]  tomcatId=tomcat3  level=1  lb_factor=10  [ajp13:localhost:8009]  channel=channel.socket:localhost:8009  [ajp13:server1:8009]  channel=channel.socket:server1:8009  [ajp13:server2:8009]  channel=channel.socket:server2:8009 
image from book

In this example you define three workers, one on the local server and two on remote servers (server1 and server2). By setting tomcat1’s level to 0 and the remote workers to 1, you’re asking the Web server to use the local worker for all requests; should this worker fail, it should use the remote cluster. In the remote cluster, server1 has preference over server2 and will be used more often.

Configuring Tomcat for Load Balancing

For load balancing, you need to specify the jvmRoute attribute of the <Engine> directive in server.xml for each Tomcat worker. This unique ID ensures the seamless session feature is activated, and it must be unique across all the available Tomcat workers participating in the load-balancing cluster.

This unique identifier will be appended to the session ID generated for that Tomcat worker. Using this, the front-end Web server will forward any particular session request to the appropriate Tomcat worker.

This configuration is the same no matter which Web server or version of mod_jk you’re using. To continue the example, add a unique jvmRoute attribute to each Tomcat worker’s server.xml file, as detailed in Listing 9-17.

Listing 9-17: Configuring Tomcat Workers for Tomcat 1 and Tomcat 2

image from book
 <!-- Define the top-level container in our container hierarchy -->  <!-- Tomcat 1's connector -->  <Engine name="Catalina"          defaultHost="localhost"          debug="0"          jvmRoute="tomcat1">  <!-- Define the top-level container in our container hierarchy -->  <!-- Tomcat 2's connector -->  <Engine name="Catalina"          defaultHost="localhost"          debug="0"          jvmRoute="tomcat2"> 
image from book

Before you run the Tomcat workers for testing, you’ll need to handle the CATALINA_HOME environment variable. In most cases, when you run a single Tomcat instance, you set the CATALINA_HOME as an environment variable so that it’s available once your system boots up. This can create a problem when you want to run two instances of Tomcat on the same machine. This is because each of the Tomcat instances will need a unique CATALINA_HOME variable.

You can handle this by resetting CATALINA_HOME. Edit the catalina.sh (or catalina.bat for Windows) file located in the second Tomcat’s CATALINA_HOME/bin directory, and add the two lines in Listing 9-18 at the start of it to point to the appropriate directories.

Listing 9-18: Setting CATALINA_HOME for Tomcat workers

image from book
 #For Linux/ Unix Systems:  #$JAVA_HOME=/usr/java/j2sdk1.4.2  #$CATALINA_HOME=/usr/java/jakarta-tomcat-X  REM For Windows:  %JAVA_HOME%=c:\j2sdk1.4.2  %CATALINA_HOME%=c:\Jakarta-tomcat-X 
image from book

If you’re using mod_jk2, edit CATALINA_HOME/conf/jk2.properties and add the following line on the second Tomcat instance:

 channelSocket.port=8010 

Now that you’ve finished configuring your load-balancing setup, you need to make sure all the Tomcat instances are up and running properly. To do this, create a file named index.jsp and put it in the tomcatBook context of Tomcat 1, as shown in Listing 9-19.

Listing 9-19: Tomcat 1’s index.jsp file

image from book
 <html>    <body>      <h1><font color="red">Session Served By Tomcat 1</font></h1>      <table align="centre" border="1">        <tr>          <td>Session ID</td>          <td>${pageContext.session.id}</td>        </tr>        <tr>          <td>Created on</td>          <td>${pageContext.session.creationTime}</td>        </tr>      </table>    </body>  </html> 
image from book

Copy this file into the tomcatBook context of the other Tomcat worker. To help you see which Tomcat instance has processed a request, edit index.jsp by changing this line

 <h1><font color="red">Session Served By Tomcat 1</font></h1> 

to the following for Tomcat 2:

 <h1><font color="blue>"Session Served By Tomcat 2</font></h1> 

Testing the Load Balancing Behavior

To test this, first verify that your Web server is serving the static content properly by browsing to the URL http://localhost/. You should see the default Web server index.html page. Now, test that Tomcat is serving the index.jsp page by browsing to the URL http://localhost/tomcatBook/index.jsp. You’ll be served by one of the two Tomcat instances. If Tomcat 1 served the page, you’ll get the page shown in Figure 9-4.

image from book
Figure 9-4: Tomcat 1 serving index.jsp

Similarly, if Tomcat 2 worker serves your request, you’ll get the page with the blue heading and the “Session Served By Tomcat 2” message followed by its session data.

Note the session ID in the first row of the table. Refresh your browser, and you’ll notice that no matter how many hits you make, the session ID remains the same. This indicates that the load balancer is keeping the current session contents intact.

Now, open another window with the same URL. This time the other Tomcat worker will handle your request. This is because the Web server is using a round-robin algorithm.

To test the fail-over aspect of load balancing, shut down one of the Tomcat workers. You’ll then get output only from the remaining worker. If you start the idle worker again, the load balancer will start using it as soon as it finds that the server is up. It periodically checks the status of the worker and will start using it as soon as it’s made available.

Now that you know how to configure load balancing, you use the clustering knowledge you gained in Chapter 7. This means you can deploy Web applications across multiple Tomcat workers by dropping an application’s WAR file into a node’s watched deployment directory.



Pro Jakarta Tomcat 5
Pro Apache Tomcat 5/5.5 (Experts Voice in Java)
ISBN: 1590593316
EAN: 2147483647
Year: 2004
Pages: 94

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net