Clustering Apache Tomcat. Session replication and high availability.
Apache Tomcat Clustering and load balancing
Here is conceptual solution:
Configure apache tomcat for session replication:
1) Uncomment Cluster element in server.xml on both tomcat web servers2) Change tcpListenPort for each web server (must be different)
3) Change Engine element by adding jvmRoute="tomcatA" for first tomcat web server and jvmRoute="tomcatB" for second tomcat webserver.
Here are server.xml configuration files:
Server.xml for tomcat A:
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcatA">
... <Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster" managerClassName="org.apache.catalina.cluster.session.DeltaManager" expireSessionsOnShutdown="false" useDirtyFlag="true" notifyListenersOnReplication="true"> <Membership className="org.apache.catalina.cluster.mcast.McastService" mcastAddr="228.0.0.4" mcastPort="45564" mcastFrequency="500" mcastDropTime="3000"/> <Receiver className="org.apache.catalina.cluster.tcp.ReplicationListener" tcpListenAddress="auto" tcpListenPort="4006" tcpSelectorTimeout="100" tcpThreadCount="6"/> <Sender className="org.apache.catalina.cluster.tcp.ReplicationTransmitter" replicationMode="pooled" ackTimeout="15000" waitForAck="true"/> <Valve className="org.apache.catalina.cluster.tcp.ReplicationValve" filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/> <Deployer className="org.apache.catalina.cluster.deploy.FarmWarDeployer" tempDir="/tmp/war-temp/" deployDir="/tmp/war-deploy/" watchDir="/tmp/war-listen/" watchEnabled="false"/> <ClusterListener className="org.apache.catalina.cluster.session.ClusterSessionListener"/> </Cluster> .... |
Server.xml for tomcat B:
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcatB">
... <Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster" managerClassName="org.apache.catalina.cluster.session.DeltaManager" expireSessionsOnShutdown="false" useDirtyFlag="true" notifyListenersOnReplication="true"> <Membership className="org.apache.catalina.cluster.mcast.McastService" mcastAddr="228.0.0.4" mcastPort="45564" mcastFrequency="500" mcastDropTime="3000"/> <Receiver className="org.apache.catalina.cluster.tcp.ReplicationListener" tcpListenAddress="auto" tcpListenPort="4007" tcpSelectorTimeout="100" tcpThreadCount="6"/> <Sender className="org.apache.catalina.cluster.tcp.ReplicationTransmitter" replicationMode="pooled" ackTimeout="15000" waitForAck="true"/> <Valve className="org.apache.catalina.cluster.tcp.ReplicationValve" filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/> <Deployer className="org.apache.catalina.cluster.deploy.FarmWarDeployer" tempDir="/tmp/war-temp/" deployDir="/tmp/war-deploy/" watchDir="/tmp/war-listen/" watchEnabled="false"/> <ClusterListener className="org.apache.catalina.cluster.session.ClusterSessionListener"/> </Cluster> .... |
Also we should add <distributable/> between <web-app> into $TOMCAT_HOME/webapps/ROOT/WEB-INF/web.xml:
<web-app> <distributable/> <context-param> < ... </web-app> |
Adding load balancer
Download Apache webservers and mod_jk.Install apache web server. Copy mod_jk.so into "C:\Program Files\Apache Software Foundation\Apache2.2\modules".
Update httpd.conf as shown below:
LoadModule jk_module modules/mod_jk.so <IfModule jk_module> JkWorkersFile "C:/Program Files/Apache Software Foundation/Apache2.2/conf/workers.properties" JkLogFile "C:/Program Files/Apache Software Foundation/Apache2.2/logs/mod_jk.log" JkLogLevel info JkLogStampFormat "[%a %b %d %H:%M:%S %Y] " JkMount /* loadbalancer </IfModule> |
Create workers.properties file under "C:/Program Files/Apache Software Foundation/Apache2.2/conf/":
worker.list=loadbalancer worker.tomcata.type=ajp13 worker.tomcata.host=localhost worker.tomcata.port=8009 worker.tomcata.lbfactor=1 worker.tomcata.cachesize=10 worker.tomcata.cache_timeout=600 worker.tomcata.socket_keepalive=1 worker.tomcata.socket_timeout=300 worker.tomcatb.type=ajp13 worker.tomcatb.host=localhost worker.tomcatb.port=8109 worker.tomcatb.lbfactor=1 worker.tomcatb.cachesize=10 worker.tomcatb.cache_timeout=600 worker.tomcatb.socket_keepalive=1 worker.tomcatb.socket_timeout=300 worker.loadbalancer.type=lb worker.loadbalancer.balanced_workers=tomcata,tomcatb worker.loadbalancer.method=R |
Change server.xml as follows:
Tomcat A:
<Connector port="8009" enableLookups="false" redirectPort="443" protocol="AJP/1.3" />Tomcat B:
<Connector port="8109" enableLookups="false" redirectPort="443" protocol="AJP/1.3" />Now, after all is set, your environment is clustered with session replication. Please note you can configure your web servers to run in failover mode. Meaning, only one web server is working, while second is idle. If some reason the working web server goes down, the backup server will take over.
You can configure your web servers to run in failover mode by changing workers.properties:
worker.list=loadbalancer worker.tomcata.type=ajp13 worker.tomcata.host=localhost worker.tomcata.port=8009 worker.tomcata.lbfactor=1 worker.tomcata.cachesize=10 worker.tomcata.cache_timeout=600 worker.tomcata.socket_keepalive=1 worker.tomcata.socket_timeout=300 worker.tomcata.redirect=tomcatb worker.tomcatb.type=ajp13 worker.tomcatb.host=localhost worker.tomcatb.port=8109 worker.tomcatb.lbfactor=1 worker.tomcatb.cachesize=10 worker.tomcatb.cache_timeout=600 worker.tomcatb.socket_keepalive=1 worker.tomcatb.socket_timeout=300 worker.tomcatb.activation=disabled worker.loadbalancer.type=lb worker.loadbalancer.balanced_workers=tomcata,tomcatb |