From: <¥Ñ Microsoft Internet Explorer 5 Àx¦s>
Subject: Apache 2.x + Tomcat 4.x + Load Balancing (or Private JVMs)
Date: Sat, 19 Jul 2003 22:04:33 +0800
MIME-Version: 1.0
Content-Type: multipart/related;
	boundary="----=_NextPart_000_0006_01C34E41.BC026460";
	type="text/html"
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1106

This is a multi-part message in MIME format.

------=_NextPart_000_0006_01C34E41.BC026460
Content-Type: text/html;
	charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Content-Location: http://raibledesigns.com/tomcat/index.html

=EF=BB=BF<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" =
"http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
<HTML xmlns=3D"http://www.w3.org/1999/xhtml"><HEAD><TITLE>Apache 2.x + =
Tomcat 4.x + Load Balancing (or Private JVMs)</TITLE>
<META http-equiv=3DContent-Type content=3D"text/html; charset=3Dutf-8">
<STYLE type=3Dtext/css media=3Dall>BODY {
	FONT-SIZE: 80%; COLOR: black; FONT-FAMILY: Arial,Helvetica,san-serif; =
BACKGROUND-COLOR: #eee
}
DIV.canvas {
	BORDER-RIGHT: black 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: black =
1px solid; PADDING-LEFT: 10px; BACKGROUND: #fff; PADDING-BOTTOM: 10px; =
MARGIN-LEFT: auto; BORDER-LEFT: black 1px solid; WIDTH: 80%; =
MARGIN-RIGHT: auto; PADDING-TOP: 10px; BORDER-BOTTOM: black 1px solid
}
P.c7 {
	FONT-WEIGHT: bold
}
DIV.c5 {
	TEXT-ALIGN: center
}
SPAN.c2 {
	FONT-SIZE: 120%
}
TD.c1 {
	FONT-SIZE: 130%; COLOR: white
}
SPAN.c1 {
	BACKGROUND: none transparent scroll repeat 0% 0%; COLOR: red
}
PRE {
	FONT-SIZE: 12px
}
CODE {
	FONT-SIZE: 12px
}
DIV.highlight {
	BORDER-RIGHT: black 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: black =
1px solid; PADDING-LEFT: 10px; BACKGROUND: #ffc; PADDING-BOTTOM: 10px; =
BORDER-LEFT: black 1px solid; COLOR: black; PADDING-TOP: 10px; =
BORDER-BOTTOM: black 1px solid
}
P.testedBy {
	BORDER-TOP: black 1px dashed; FONT-SIZE: 0.9em; BACKGROUND: none =
transparent scroll repeat 0% 0%; COLOR: #666; PADDING-TOP: 5px
}
IMG.w3c {
	BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; FLOAT: right; =
BORDER-BOTTOM-WIDTH: 0px; WIDTH: 88px; HEIGHT: 31px; BORDER-RIGHT-WIDTH: =
0px
}
DIV#errata {
	BORDER-RIGHT: silver 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: silver =
1px solid; MARGIN-TOP: 10px; PADDING-LEFT: 5px; BACKGROUND: #ffd; =
PADDING-BOTTOM: 5px; OVERFLOW: auto; BORDER-LEFT: silver 1px solid; =
WIDTH: 98%; COLOR: #000; PADDING-TOP: 5px; BORDER-BOTTOM: silver 1px =
solid; HEIGHT: 150px
}
</STYLE>

<STYLE type=3Dtext/css media=3Dprint>DIV.canvas {
	BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: =
0px; WIDTH: 100%; BORDER-RIGHT-WIDTH: 0px
}
DIV#errata {
	OVERFLOW: visible
}
</STYLE>

<META content=3D"MSHTML 6.00.2800.1106" name=3DGENERATOR></HEAD>
<BODY>
<DIV class=3Dcanvas>
<TABLE width=3D"100%">
  <TBODY>
  <TR>
    <TD>
      <TABLE border=3D0>
        <TBODY>
        <TR>
          <TD class=3Dc1 width=3D80 =
bgColor=3D#97092a><B>&nbsp;UBEANS&nbsp; </B></TD>
          <TD><SPAN class=3Dc2><B>Technologies</B></SPAN> =
</TD></TR></TBODY></TABLE>
      <DIV class=3Dc5>
      <H3><B>Apache 2.x + Tomcat 4.x <BR>+ Load Balancing (or Private =
JVMs)</B>=20
      </H3></DIV>
      <P>January 24, 2002 by <A =
href=3D"mailto:pascal.forget@ubeans.com">Pascal=20
      Forget</A><BR>Revised September 25, 2002 by <A=20
      href=3D"mailto:matt@raibledesigns.com">Matt Raible</A><BR>Original =
Article=20
      at <A=20
      =
href=3D"http://www.ubeans.com/tomcat/">http://www.ubeans.com/tomcat/</A>.=
=20
      </P>
      <P>This article contains step by step instructions for configuring =
an=20
      Apache 2.x web server which handles static content and delegates =
JSP (Java=20
      Server Pages) and Servlet requests to two Tomcat 4.x servers using =
AJP 13=20
      connectors and a load balancing worker. </P>
      <DIV id=3Derrata>
      <H3>User Submitted Errata</H3><STRONG>2002-12-11, Robert Dietrick, =
re:=20
      Tomcat 4.1.x</STRONG> <PRE>Tomcat is now distributed with a =
jk2.properties file (in the conf/=20
subdirectory), which needs to be edited in order to change the port=20
number on which the JK2 connector listens.  Regardless of the port you=20
specify in the connector definition in server.xml, you'll still need to=20
change this property file, or else Tomcat will start the listener on the =

default port (8009).

Here are the changes I made:

In each of the tomcat instances' conf/ directory you'll find a=20
jk.properties file.  Open each one in an editor and uncomment and change =

the line which reads
# channelSocket.port=3D8019

to the following for each tomcat instance
tomcat1:
channelSocket.port=3D11009

tomcat2:
channelSocket.port=3D12009

</PRE></DIV>
      <H3>Introduction </H3>
      <P>Apache 2.0 is a standards compliant, fast and mature web server =
which=20
      excels at delivering static content such as static HTML pages and =
images.=20
      The Tomcat web server is great for serving Java Server Pages and =
servlets,=20
      but it is not as fast as Apache for delivering static content. =
</P>
      <P>In order to build a fast, scalable web application, the =
requirements=20
      call for an Apache server that delegates servicing of JSP and =
servlet=20
      requests to multiple tomcat servers by using an Apache module, =
mod_jk,=20
      that performs load balancing with session affinity, also known as =
"sticky"=20
      sessions. </P>
      <P>Session affinity explained. When a client browser requests a =
JSP page=20
      for the first time, the load balancer redirects the request =
received by=20
      Apache to one of the two tomcat servers; further requests =
originating from=20
      the same client session will be automatically forwarded to the =
same tomcat=20
      server, so that the user's session data is retrieved. </P>
      <P>This document describes how I configured Apache 2.x to dispatch =
JSP and=20
      servlet requests to two Tomcat 4.x instances listening on =
different ports.=20
      This setup was done on a Linux system. Your mileage may vary. </P>
      <H3>1. Download the required software </H3>
      <UL>
        <LI><A =
href=3D"http://www.apache.org/dist/httpd/binaries/">Apache 2.x=20
        Binaries</A> (If you plan to use ssl, get the <A=20
        =
href=3D"http://raibledesigns.com/tomcat/index.html#install-unix">source</=
A>)=20

        <LI><A=20
        =
href=3D"http://jakarta.apache.org/builds/jakarta-tomcat-4.0/release/">Tom=
cat=20
        4.x Binaries</A>=20
        <LI><A=20
        =
href=3D"http://jakarta.apache.org/builds/jakarta-tomcat-connectors/jk/rel=
ease/v1.2.0/bin/">The=20
        JK module</A> </LI></UL>
      <H3>2. Compile, Install and Configure Apache </H3>
      <P class=3Dc7>2.1 Install Apache. </P>
      <BLOCKQUOTE>
        <P>Linux: <CODE>gunzip</CODE> the <CODE>*.gz</CODE> you =
downloaded,=20
        <CODE>untar</CODE> and run <CODE>install-bindist.sh</CODE></P>
        <DIV class=3Dhighlight><A id=3Dinstall-unix =
name=3Dinstall-unix></A>For *nux,=20
        to install Apache 2.0.42 with mod_sll installed, you will need =
to=20
        compile from source:=20
        <P>I used <A=20
        =
href=3D"http://httpd.apache.org/docs-2.0/install.html">http://httpd.apach=
e.org/docs-2.0/install.html</A>=20
        as a reference.</P>
        <P><CODE>$ lynx <A=20
        =
href=3D"http://www.apache.org/dist/httpd/httpd-2.0.42.tar.gz">http://www.=
apache.org/dist/httpd/httpd-2.0.42.tar.gz</A></CODE><BR><CODE>$=20
        gzip -d httpd-2.0.42.tar.gz</CODE><BR><CODE>$ tar xvf=20
        httpd-2.0.42.tar</CODE><BR><CODE>$ ./configure =
--enable-mods-shared=3Dmost=20
        --enable-ssl=3Dshared</CODE><BR><CODE>$ make</CODE><BR><CODE>$ =
make=20
        install</CODE></P>Then download <A=20
        =
href=3D"http://jakarta.apache.org/builds/jakarta-tomcat-connectors/jk/rel=
ease/v1.2.0/bin/">mod_jk-2.0.42.so</A>=20
        and put it into your <CODE>modules</CODE> directory and rename =
it=20
        <CODE>mod_jk.so</CODE>. </DIV>
        <P><BR>Windows: Execute the downloaded executable and install.=20
      </P></BLOCKQUOTE>
      <P class=3Dc7>2.2 Configure the JK Module in httpd.conf </P>
      <P>Edit the Apache server's configuration file =
<CODE>httpd.conf</CODE>=20
      which is located in the <CODE>/usr/local/apache2/conf</CODE> =
directory.=20
      </P>
      <P><B>2.2.1</B> Below "# LoadModule foo_module =
modules/mod_foo.so", insert=20
      the following lines: </P><PRE>#
# Load mod_jk
#
LoadModule jk_module modules/mod_jk.so

#
# Configure mod_jk
#
JkWorkersFile conf/workers.properties
JkLogFile logs/mod_jk.log
JkLogLevel info
</PRE>
      <P><SPAN class=3Dc1>NOTE:</SPAN> You will need to change=20
      <STRONG>mod_jk.so</STRONG> to <STRONG>mod_jk.dll</STRONG> for =
Windows.=20
</P>
      <P><B>2.2.2</B> Below the "DocumentRoot" line, insert the =
following two=20
      lines: </P><PRE>JkMount /*.jsp loadbalancer
JkMount /servlet/* loadbalancer
</PRE>
      <P class=3Dc7>2.3 Create the workers.properties file </P>
      <P>Now we will create a file called worker.properties, and we will =
place=20
      it under /usr/local/apache2/conf. The worker.properties file tells =
Apache=20
      about the various Tomcat servers that are running, and on which =
port they=20
      are listening. </P>
      <P>In my setup, I installed the two Tomcat servers in different=20
      directories, on the same machine as Apache. Feel free to put your =
Tomcat=20
      servers on different machines. </P>
      <P>I made the first Tomcat server's AJP13 connector listen on port =
11009=20
      instead of the default port which is 8009, and the second one =
listens on=20
      port 12009. </P>
      <P>I have decided to name my tomcat servers tomcat1 and tomcat2. =
This is=20
      purely my choice. </P><SPAN>Create the file exactly like =
this:</SPAN> <PRE>#
# workers.properties=20
#

# In Unix, we use forward slashes:
ps=3D/

# list the workers by name

worker.list=3Dtomcat1, tomcat2, loadbalancer

# ------------------------
# First tomcat server
# ------------------------
worker.tomcat1.port=3D11009
worker.tomcat1.host=3Dlocalhost
worker.tomcat1.type=3Dajp13

# Specify the size of the open connection cache.
#worker.tomcat1.cachesize

#
# Specifies the load balance factor when used with
# a load balancing worker.
# Note:
#  ----&gt; lbfactor must be &gt; 0
#  ----&gt; Low lbfactor means less work done by the worker.
worker.tomcat1.lbfactor=3D100


# ------------------------
# Second tomcat server
# ------------------------
worker.tomcat2.port=3D12009
worker.tomcat2.host=3Dlocalhost
worker.tomcat2.type=3Dajp13

# Specify the size of the open connection cache.
#worker.tomcat2.cachesize

#
# Specifies the load balance factor when used with
# a load balancing worker.
# Note:
#  ----&gt; lbfactor must be &gt; 0
#  ----&gt; Low lbfactor means less work done by the worker.
worker.tomcat2.lbfactor=3D100


# ------------------------
# Load Balancer worker
# ------------------------

#
# The loadbalancer (type lb) worker performs weighted round-robin
# load balancing with sticky sessions.
# Note:
#  ----&gt; If a worker dies, the load balancer will check its state
#        once in a while. Until then all work is redirected to peer
#        worker.
worker.loadbalancer.type=3Dlb
worker.loadbalancer.balanced_workers=3Dtomcat1, tomcat2

#
# END workers.properties
#

</PRE>
      <P>That's it, we're done with Apache. For more information on=20
      workers.properties and various settings, see the <A=20
      style=3D"FONT-WEIGHT: bold"=20
      =
href=3D"http://jakarta.apache.org/tomcat/tomcat-4.1-doc/jk2/jk/workershow=
to.html">Workers=20
      HowTo</A>. </P>
      <H3>3. Install and Configure the Tomcat Servers </H3>
      <P>Now let's suppose that Java 1.4.x is installed under=20
      /usr/local/jdk1.4.x/. Create two Tomcat 4.x servers and install =
them under=20
      /usr/local/: </P><PRE>   tar fvxz jakarta-tomcat-4.x.tar.gz
   mv jakarta-tomcat-4.x /usr/local/tomcat1=20
   cp -R /usr/local/tomcat1 /usr/local/tomcat2

</PRE>
      <P>In both /usr/local/tomcat1 and /usr/local/tomcat2, the same =
files will=20
      be modified. I here by present the modifications made to the files =

      contained in the /usr/local/tomcat1 directory tree structure. You =
should=20
      also apply the same changes to the corresponding files located =
under the=20
      /usr/local/tomcat2 directory tree structure. </P>
      <P class=3Dc7>3.1 Modify catalina.sh </P>
      <P>In my many years of consulting, I have learned not to rely on=20
      environment variables which can be unset by ignorant or malicious =
people.=20
      This is why I explicitely set the JAVA_HOME and CATALINA_HOME =
variables=20
      directly in the catalina.sh file. </P>
      <P>At line 32, before the "# ----- Verify and Set Required =
Environment=20
      Variables " line, insert the following two lines: </P><PRE>    =
JAVA_HOME=3D/usr/local/jdk1.4 ; export JAVA_HOME
    CATALINA_HOME=3D/usr/local/tomcat1 ; export CATALINA_HOME
</PRE>
      <P>(Set CATALINA_HOME to /usr/local/tomcat2 in=20
      /usr/local/tomcat2/conf/catalina.sh) </P>
      <P class=3Dc7>3.2 Modify conf/server.xml </P>
      <P class=3Dc7>3.2.1 Add a unique jvmRoute to the Catalina engine =
</P>
      <P>Near line 100, replace: </P><PRE>    &lt;Engine =
name=3D"Standalone" defaultHost=3D"localhost" debug=3D"0"&gt;
</PRE>
      <P>with: </P><PRE>    &lt;Engine jvmRoute=3D"tomcat1" =
name=3D"Standalone" defaultHost=3D"localhost" debug=3D"0"&gt;
</PRE>
      <P>For tomcat2, put jvmRoute=3D"tomcat2". </P>
      <P><B>3.2.2</B> Change the control port </P>
      <P>At line 13, replace: </P><PRE>    &lt;Server port=3D"8005"
</PRE>
      <P>with: </P><PRE>    &lt;Server port=3D"11005"
</PRE>
      <P>For the tomcat2 server, replace port 8005 with 12005. This will =
prevent=20
      the two servers from conflicting. </P>
      <P><B>3.2.3</B> Change the AJP13 port </P>
      <P>At line 75, in the AJP 13 connector definition, replace: =
</P><PRE>    port=3D"8009"
</PRE>
      <P>with: </P><PRE>    port=3D"11009"
</PRE>
      <P>For the tomcat2 server, replace port 8009 with 12009. </P>
      <P><B>3.2.4</B> Disable the standalone HTTP port </P>
      <P>We don't want or need our tomcat servers to directly respond to =
HTTP=20
      requests. So we comment out the HttpConnector section between =
lines and 58=20
      in the server.xml file. </P>
      <P>Example: </P><PRE>&lt;!-- Define a non-SSL HTTP/1.1 Connector =
on port 8080 --&gt;
&lt;!--
    &lt;Connector =
className=3D"org.apache.catalina.connector.http.HttpConnector"
               port=3D"8080" minProcessors=3D"5" maxProcessors=3D"75"
               enableLookups=3D"true" redirectPort=3D"8443"
               acceptCount=3D"10" debug=3D"0" =
connectionTimeout=3D"60000"/&gt;
--&gt;   =20
</PRE>
      <P><SPAN class=3Dc1>NOTE:</SPAN> If you <EM>don't</EM> comment =
this out, you=20
      will need to change the port numbers so they don't conflict =
between tomcat=20
      instances. </P>
      <P><B>3.2.5</B> Disable the WARP connector </P>
      <P>At line 314, comment out the =
&lt;Connector...WarpConnector...&gt; tag.=20
      </P>
      <P>Example: </P><PRE>&lt;Service name=3D"Tomcat-Apache"&gt;
&lt;!--
    &lt;Connector =
className=3D"org.apache.catalina.connector.warp.WarpConnector"
     port=3D"8008" minProcessors=3D"5" maxProcessors=3D"75"
     enableLookups=3D"true" appBase=3D"webapps"
     acceptCount=3D"10" debug=3D"0"/&gt;
--&gt;
</PRE>
      <P>Do not forget to do the same thing to tomcat2's server.xml =
file. </P>
      <P><SPAN class=3Dc1>NOTE:</SPAN> You might want to comment out the =
entire=20
      &lt;Service name=3D"Tomcat-Apache"&gt; element. If so, make sure =
and remove=20
      the comments within it - XML doesn't like comments within =
comments. </P>
      <P><B>3.3</B> Create test JSP pages (index.jsp) </P>
      <P><B>3.3.1</B> Create a file named <CODE>index.jsp</CODE> and put =
it in=20
      the <CODE>/usr/local/tomcat1/webapps/ROOT</CODE> directory: =
</P><PRE>&lt;html&gt;
&lt;body bgcolor=3D"red"&gt;
&lt;center&gt;
&lt;%=3D request.getSession().getId() %&gt;
&lt;h1&gt;Tomcat 1&lt;/h1&gt;
&lt;/body&gt;
&lt;/html&gt;
</PRE>
      <P><B>3.3.2</B> Create a file named <CODE>index.jsp</CODE> and put =
it in=20
      the <CODE>/usr/local/tomcat2/webapps/ROOT</CODE> directory: =
</P><PRE>&lt;html&gt;
&lt;body bgcolor=3D"blue"&gt;
&lt;center&gt;
&lt;%=3D request.getSession().getId() %&gt;
&lt;h1&gt;Tomcat 2&lt;/h1&gt;
&lt;/body&gt;
&lt;/html&gt;
</PRE>
      <H3>4. Start Tomcat1, Tomcat2 and Apache </H3><PRE>    =
/usr/local/tomcat1/bin/startup.sh
    /usr/local/tomcat2/bin/startup.sh
    /usr/local/apache2/bin/apachectl start
</PRE>
      <H3>5. Test your Installation </H3>
      <P>Now is the time to test your setup. First, verify that Apache =
serves=20
      static content. </P>
      <P>Click on: <A href=3D"http://localhost/">http://localhost/</A>. =
You should=20
      see the default Apache index.html page. </P>
      <P>Now test that tomcat (either Tomcat 1 or Tomcat 2) is serving =
Java=20
      Server Pages. </P>
      <P>Click on: <A=20
      href=3D"http://localhost/index.jsp">http://localhost/index.jsp</A> =
</P>
      <P>If you get a red page, the page was served by the tomcat1 =
server, and=20
      if you get a blue page, it was served by the tomcat2 server. </P>
      <P>Now test that session affinity - also known as sticky sessions =
- works=20
      within the load balancer. Hit the reload button of your web =
browser=20
      several times and verify that the index.jsp page you get is always =

      received from the same tomcat server. </P>
      <H3>6. Configuring Private JVMs </H3>
      <P>If you don't need load-balancing, but you are interested in =
configuring=20
      Apache/Tomcat for private Tomcat instances, you can add one of the =

      following near the end of httpd.conf: </P>
      <P><STRONG>6.1</STRONG> Name-based (1 IP address or NIC). =
</P><PRE>NameVirtualHost *

&lt;VirtualHost *&gt;
ServerName localhost1
JkMount /*.jsp tomcat1
JkMount /servlet/* tomcat1
&lt;/VirtualHost&gt;

&lt;VirtualHost *&gt;
ServerName localhost2
JkMount /*.jsp tomcat2
JkMount /servlet/* tomcat2
&lt;/VirtualHost&gt;
</PRE>
      <P><STRONG>6.2</STRONG> IP-based (different IP for each site). =
</P><PRE># First Virtual Host.
#
&lt;VirtualHost 192.168.0.1:80&gt;
ServerName localhost
JkMount /*.jsp tomcat1
JkMount /servlet/* tomcat1
&lt;/VirtualHost&gt;

# Second Virtual Host.
#
&lt;VirtualHost 192.168.0.2:80&gt;
ServerName localhost2
JkMount /*.jsp tomcat2
JkMount /servlet/* tomcat2
&lt;/VirtualHost&gt;
</PRE>
      <P>Where the serverNames are fully-qualified host names in a DNS =
Server.=20
      More information can be found at <A=20
      =
href=3D"http://httpd.apache.org/docs-2.0/vhosts/">http://httpd.apache.org=
/docs-2.0/vhosts/</A>.=20
      </P>
      <P><SPAN class=3Dc1>NOTE:</SPAN> When using SSL with multiple =
Virtual Hosts,=20
      you must use an ip-based configuration. This is because SSL =
requires you=20
      to configure a specific port (443), whereas name-based specifies =
all ports=20
      (*). You might the following error if you try to mix name-based =
virtual=20
      hosts with SSL.</P>
      <P><CODE>[error] VirtualHost _default_:443 -- mixing * ports and =
non-*=20
      ports with a NameVirtualHost address is not supported, proceeding =
with=20
      undefined results</CODE></P>
      <H3>Starting Apache and Tomcat on Startup</H3>
      <P>To start Apache and Tomcat on startup in a *nix environment, =
see <A=20
      =
href=3D"http://www.raibledesigns.com/tomcat/boot-howto.html">http://www.r=
aibledesigns.com/tomcat/boot-howto.html</A>.=20

      <P>On Windows, you can install Tomcat as a service.</P>
      <H3>Supplemental Information </H3>
      <P><B>Question 1:</B> <BR>Why did you choose to use the AJP13 =
connector=20
      rather than the WARP connector that is recommended? </P>
      <P><B>Answer:</B> <BR>The warp connector is used in conjunction =
with=20
      mod_webapp, and mod_webapp does not currently support load =
balancing. </P>
      <P>Also, I found the documentation for the warp connector on the =
Jakarta=20
      web site to be quite lacking. See: <A=20
      =
href=3D"http://jakarta.apache.org/tomcat/tomcat-4.0-doc/config/warp.html"=
>http://jakarta.apache.org/tomcat/tomcat-4.0-doc/config/warp.html</A>=20
      </P>
      <P>I know that the future lies in the warp connector, but in the =
meantime,=20
      I needed something. The documentation did not explain to me =
exactly what=20
      benefits I would get from using the Warp connector as opposed to =
AJP13.=20
      </P>
      <P><B>Question 2:</B> <BR>You might specify that creating two =
instances of=20
      the tomcat installation is not needed as you can share the main =
binaries=20
      and libs by specifying 2 distinct CATALINA_BASE variables. </P>
      <P>True, but in real life the two tomcat servers are usually =
located on=20
      two different machines. My setup might be overkill for a single =
machine=20
      setup, but it's easy to tar up the "tomcat2" server and put it on =
a second=20
      machine; you just have to change "localhost" to the appropriate =
machine=20
      name in /usr/local/apache2/conf/workers.properties and you're =
done. </P>
      <P><B>Question 3:</B> <BR>What does not work and what does work in =
load=20
      balancing? </P>
      <P><B>Answer:</B> <BR>Load balancing works great. </P>
      <P><B>1. Session affinity works</B> <BR>Which means that when a =
client=20
      browser is directed to a Tomcat server by the load balancer, then =
future=20
      queries from that same browser session will always be directed to =
the same=20
      tomcat server. This is important because sessions that are created =
in a=20
      specific tomcat server, say "tomcat1", do not exist in the other =
server=20
      "tomcat2", and thus if the client was directed to another tomcat =
server=20
      than the one where his session is stored, then all his session =
data would=20
      be lost. </P>
      <P>Some people are working on sessions that will be replicated =
across all=20
      tomcat servers in the cluster, so I'll just wait for it to become=20
      available rather than make a homebrewed distributed session =
mechanism.=20
</P>
      <P>The downside of not having sessions replicated across all the =
tomcat=20
      servers in the cluster is that if one tomcat server dies, all the =
sessions=20
      that it contained are lost, which usually makes a lot of unhappy =
users.=20
      </P>
      <P><B>2. Failover works</B> <BR>If one tomcat server dies, the =
load=20
      balancer then "rebalances" the queries to the remaining tomcat =
servers.=20
      </P>
      <P><B>3. Failback works</B> <BR>When a tomcat server comes back =
from the=20
      dead, the load balancer automatically starts to send queries to =
it. So you=20
      can actually add capacity to your cluster on the fly. </P>
      <P><B>4. Weighted load balancing works</B> <BR>In=20
      /usr/local/apache2/conf/workers.properties, I assigned a load =
balancing=20
      factor of 100 to both "tomcat1" and "tomcat2" servers. Then I =
changed the=20
      lbfactor of "tomcat1" to 101, and I saw that effectively the =
"tomcat1"=20
      server received more load than the "tomcat2" server, which is =
something=20
      you want when for example your "tomcat1" server is a faster/newer =
machine=20
      while your "tomcat2" server is a slower machine which cannnot take =
as much=20
      load as the other one. </P>
      <H3>References </H3>
      <P>For more information, you should read <A=20
      =
href=3D"http://www.samag.com/documents/s=3D1155/sam0101a/0101a.htm">An =
Apache=20
      Load Balancing Cluster</A>. It talks about mod_jserv, which is now =
mod_jk,=20
      and it uses JServ instead of Tomcat, but the concepts are still =
valid.=20
</P>
      <H3>Conclusion </H3>
      <P>The list of steps that are required to obtain a scalable web=20
      application solution based on Apache 2.x and a group of distibuted =
Tomcat=20
      servers are well-defined and if you follow the receipe exactly, =
you should=20
      be able to achieve success. </P>
      <P>I hope that this article will be helpful to you. Good Luck. =
</P>
      <P><A href=3D"mailto:pascal.forget@ubeans.com">Pascal Forget</A> =
</P>
      <P class=3DtestedBy><A =
href=3D"http://validator.w3.org/check/referer"><IMG=20
      class=3Dw3c alt=3D"Valid XHTML 1.0!"=20
      src=3D"http://www.w3.org/Icons/valid-xhtml10"></A> These =
instructions where=20
      tested by <A href=3D"mailto:matt@raibledesigns.com">Matt =
Raible</A> on=20
      Windows XP (SP1) / Red Hat Linux 7.3 with J2SE 1.4.1, Apache =
2.0.40 (for=20
      Linux, 2.0.42 for Windows), and Tomcat 4.0.5.=20
</P></TD></TR></TBODY></TABLE></DIV></BODY></HTML>

------=_NextPart_000_0006_01C34E41.BC026460
Content-Type: application/octet-stream
Content-Transfer-Encoding: base64
Content-Location: http://www.w3.org/Icons/valid-xhtml10

iVBORw0KGgoAAAANSUhEUgAAAFgAAAAfCAMAAAEjEcpEAAACiFBMVEUAAADe5+fOezmtra3ejEKl
hELvvWO9WlrehELOe3vepaWclHvetVLGc3PerVKcCAj3vVqUjHOUe1JjlL0xOUpjjL2UAAC91ueM
rc7vrVKlvdbW3u+EpcbO3ufO1ucYWpSMKQi9SiF7e3taWkoQEAiMczkQSoxaUkpzc3O1lEoICACE
azEhGAgIAACEYzFra2utjELWcznGnEr/7+9jY2POazHOYzGta2NShLVrlL05OUqctdacCADGa2uc
AADGpVqUtc61ORg5OTmlUikYGAiUezl7YzEYEAiUczkxMTG9nEqtIRDe3t4AMXu9lEoQCACMazEA
KXspKSmljFrW1ta1jELOzs7n7/fGxsa9pVqEOSkpY5xznL29tZxahLXOpVr/99ZrY1L/79ZjUilj
SikAOYTvxmMAMYScezmchFqUczGtlFp7c2utjFqUlJStxt73///39/9Ce61CSkq9xsZznMbW5+9C
c62MjIxCQkrv9/fv7/fOzsbnlErWjIz/3mtCORhza1IpIRBzWjH/1mtCMRhzY1L/zmvnvVpSQiHO
pVJrUinntVr3zmOEc1L3xmNaWlq1nFo5QkrGWim1lFoISpRSUlK1zt4hWpwASoz///////8xa6WU
aykAQoxKe61KSkp7nMbWtWPe5+9jWlL39/f39/fWrWNCQkLera3nvWPv7+85MRjntWPetVp7c1Ix
KRCUlHtKORh7a1IxIRCUjHtaSiHWrVIpIQhzWinvvVpaQiH/1mPWpVKMe1L/zmP/xmNrUiGErc4Y
GBj/73PG1ucQWpT/53O9nFoQUpS1SiEQEBC9zt69vb05c6UISoxSUko5a6UICAhSSkohUpS1tbXe
tWMAQoSUgD+kAAAA2HRSTlP/////////iP9sSf//dP//////////////////////////////////
//////////////8M////////////ef//////////////////////////////////////////////
//////////////////////////////////////9d////////////////////////////////////
AP//////////////CP//RP//////////////////////////////////////////////////////
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
osmq7jsZAJsAAAAASUVORK5CYII=

------=_NextPart_000_0006_01C34E41.BC026460--
