You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Andreas Daab <an...@tectura.com> on 2006/02/03 11:30:26 UTC

Tomcat loadbalancing howto

Hi,

in the thread "Tomcat-5.5.12 less robust than 5.0.28" I told about
problems with the scaling of tomcat. We have more incoming calls to
tomcat than tomcat can handle. Windows 2003 seems to have problems to
distribute the threads to the cpu if the number of threads is bigger
than 50. The cpu load is 15 % or less and Tomcat is not able to serve
web pages anymore. The only solution is to force the load sharing with
horizontal cluster and loadbalacing. I want to share my experience with
you and wrote a short howto.

Introduction:

This howto describes how to implement loadbalancing with Apache httpd,
Tomcat and JK. I assume that you have a web application with mostly
dynamic content and use of sessions. I refer to an installation on
Windows, but the basic configuration applies to other operating systems
as well.

Software:
Apache httpd 2.0.55:
http://mirror.serversupportforum.de/apache/httpd/binaries/win32/apache_2
.0.55-win32-x86-no_ssl.msi

Tomcat 5.5.15:
http://mirrorspace.org/apache/tomcat/tomcat-5/v5.5.15/bin/apache-tomcat-
5.5.15.zip

JK 1.2.15:
http://netmirror.org/mirror/apache.org/tomcat/tomcat-connectors/jk/binar
ies/win32/jk-1.2.15/mod_jk-apache-2.0.55.so

APR 1.1.1:
http://tomcat.heanet.ie/native/1.1.1/binaries/win32/tcnative-1.dll

Installation:
First install Apache 2.0. httpd to "<basepath>", e.g. "D:\Apache". The
installer creates a directory named "Apache 2". Copy the
"mod_jk-apache-2.0.55.so" as "mod_jk.so" in the directory
"<basepath>\modules". Extract Tomcat files to the directory
"<basepath>\apache-tomcat-5.5.15" and copy it to
"<basepath>\apache-tomcat-5.5.15-1",
"<basepath>\apache-tomcat-5.5.15-2", "<basepath>\apache-tomcat-5.5.15-3"
and "<basepath>\apache-tomcat-5.5.15-4".
Copy "tcnative-1.dll" to all four tomcat "bin" directories. Deploy your
web applications to all Tomcat instances.

Configuration:
We'll start with Apache httpd. Insert the following lines in your
"httpd.conf":

<-----------------------------------------------------------------------
-------->
### Loadbalancer Tomcat
#
LoadModule jk_module modules/mod_jk.so
JkWorkersFile <basepath>/Apache2/conf/workers.properties
JkLogFile D:/Apache/Apache2/logs/mod_jk.log
# [debug/error/info]
JkLogLevel error
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
JkRequestLogFormat "%w %V %T"
JkMount /<app1> loadbalancer
JkMount /<app1>/* loadbalancer
JkMount /<app2> loadbalancer
JkMount /<app2>/* loadbalancer
# jkstatus
JkMount /jkstatus jkstatus
# Deny direct access
<Location "/<app1>/WEB-INF/">
    AllowOverride None
    deny from all
</Location>
<Location "/<app1>/META-INF/">
    AllowOverride None
    deny from all
</Location>
<Location "/<app2>/WEB-INF/">
    AllowOverride None
    deny from all
</Location>
<Location "/<app2>/META-INF/">
    AllowOverride None
    deny from all
</Location>
<-----------------------------------------------------------------------
-------->

"<app1>" and "<app2>" are your web applications. Don't forget to deny
the access
to all directories that should not be accessed via HTTP.

Now we have to configure JK. Create the following "workers.properties"
in
"<basepath>\Apache\conf":

<-----------------------------------------------------------------------
-------->
worker.list=loadbalancer,jkstatus

worker.tomcat1.port=8109
worker.tomcat1.host=localhost
worker.tomcat1.type=ajp13
worker.tomcat1.lbfactor=1
worker.tomcat1.socket_timeout=1800
worker.tomcat1.recycle_timeout=1800
worker.tomcat1.cache_timeout=1800

worker.tomcat2.port=8209
worker.tomcat2.host=localhost
worker.tomcat2.type=ajp13
worker.tomcat2.lbfactor=1
worker.tomcat2.socket_timeout=1800
worker.tomcat2.recycle_timeout=1800
worker.tomcat2.cache_timeout=1800

worker.tomcat3.port=8309
worker.tomcat3.host=localhost
worker.tomcat3.type=ajp13
worker.tomcat3.lbfactor=1
worker.tomcat3.socket_timeout=1800
worker.tomcat3.recycle_timeout=1800
worker.tomcat3.cache_timeout=1800

worker.tomcat4.port=8409
worker.tomcat4.host=localhost
worker.tomcat4.type=ajp13
worker.tomcat4.lbfactor=1
worker.tomcat4.socket_timeout=1800
worker.tomcat4.recycle_timeout=1800
worker.tomcat4.cache_timeout=1800

worker.loadbalancer.type=lb
worker.loadbalancer.sticky_sessions=true
worker.loadbalancer.sticky_session_force=false
worker.loadbalancer.balance_workers=tomcat1,tomcat2,tomcat3,tomcat4

worker.jkstatus.type=status
<-----------------------------------------------------------------------
-------->

We have a round robin loadbalancer with four Tomcats. "sticky_sessions"
is set to true to ensure persistent sessions.

Here is a basic "server.xml" for Tomcat. You have to modify the server
port (8105, 8205, 8305, 8405), the HTTP connector port (8180, 8280,
8380, 8480) and the AJP connector port (8109, 8209, 8309, 8409).

<-----------------------------------------------------------------------
-------->
<Server port="8105" shutdown="SHUTDOWN">

  <Listener className="org.apache.catalina.core.AprLifecycleListener" />
  <Listener
className="org.apache.catalina.mbeans.ServerLifecycleListener" />
  <Listener
className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"
/>
  <Listener
className="org.apache.catalina.storeconfig.StoreConfigLifecycleListener"
/>

  <GlobalNamingResources>
    <Environment name="simpleValue" type="java.lang.Integer"
value="30"/>
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
       description="User database that can be updated and saved"
           factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
          pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>

  <Service name="Catalina">
    <Connector port="8180" maxHttpHeaderSize="8192"
               maxThreads="150" minSpareThreads="25"
maxSpareThreads="75"
               enableLookups="false" redirectPort="8443"
acceptCount="100"
               connectionTimeout="20000" disableUploadTimeout="true" />
    <Connector port="8109"
               enableLookups="false" redirectPort="8443"
protocol="AJP/1.3" />
    <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">
      <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
             resourceName="UserDatabase"/>
      <Host name="localhost" appBase="webapps"
       unpackWARs="true" autoDeploy="true"
       xmlValidation="false" xmlNamespaceAware="false">
      </Host>
    </Engine>
  </Service>

</Server>
<-----------------------------------------------------------------------
-------->

With the HTTP connector you can access the installed web applications
directly, e.g. the tomcat manager application.
Add "CATALINA_HOME=<basepath>\apache-tomcat-5.5.15-1",
"CATALINA_HOME=<basepath>\apache-tomcat-5.5.15-2", ... to "startup.bat",
"shutdown.bat", "tool-wrapper.bat", "version.bat", "catalina.bat",
"digest.bat" and "service.bat".
I recommend to insert "set CATALINA_OPTS=-Xms128m -Xmx256m" in
"startup.bat" and "--JvmMs 128 --JvmMx 256" in "service.bat" or even
more, if your web application need a lot of RAM.

Testing:
First start the Tomcat instances, then Apache httpd. Test your system
with jmeter and different numbers of Tomcat to determine the correct
value. You can modify the load factor on the fly with the JK status
manager, accessable under "http://servername/jkstatus".

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org