Monday, March 16, 2015

Session replication in Tomcat

For HA solution we want to replicate the sessions among a cluster of Tomcat. In this post, we will see a simple way of replicating session. This is not load balancing as load balancing is done by putting a load balancer in front of cluster. I will show taking an example of two Tomcat. Let's call them TomcatA and TomcatB. Also we will have same war deployed on both the Tomcat. I have tried this same machine (Ubuntu 1204)  running two independent instances of Tomcat. I have to change the ports of one of the tomcat so they do not conflict with each other.

First is to tell the web application that it is distributable. For that go to web.xml and put the following tag
<distributable/>

Add the route entry in the routing table

sudo route add -net 224.0.0.0 netmask 240.0.0.0 dev eth0

The next thing to tell the tomcat that they are part of a cluster. This is done my building a multicast cluster. Put the following in the server.xml of both TomcatA and TomcatB. Put the line before </Host> tag at the end.

 <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
                 channelSendOptions="6">


<Manager className="org.apache.catalina.ha.session.DeltaManager"
             expireSessionsOnShutdown="false" notifyListenersOnReplication="true" />

          <Channel className="org.apache.catalina.tribes.group.GroupChannel">
            <Membership className="org.apache.catalina.tribes.membership.McastService"
                        address="228.0.0.4"
                        port="45564"
                        frequency="500"
                        dropTime="3000"/>
            <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
                      address="auto"
                      port="5000"
                      selectorTimeout="100"
                      maxThreads="6"/>

            <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
              <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
            </Sender>
        
<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>

<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>

<Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/>
</Channel>

          <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
                 filter=".*\.gif|.*\.js|.*\.jpeg|.*\.jpg|.*\.png|.*\.htm|.*\.html|.*\.css|.*\.txt"/>
          <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
 </Cluster>

One stackoverflow  post mentions that the configuration worked when the the Deltamanager is put in context.xml of both TomcatA and TomcatB. I was able to get this working by putting in server,xml itself. Give it a try if you run into trouble. Put the following line after <Context> tag and remove from server.xml

<Manager className="org.apache.catalina.ha.session.DeltaManager"
             expireSessionsOnShutdown="false" notifyListenersOnReplication="true" />

If your session replication is not working and you are using more than one machine or VM, make sure that the machines are in multicast cluster. You can check that by using the following command

ping -t 1 -c 2 228.0.0.4

You should see the response from the participating servers.

For debugging the cluster issues, you can enable the logging level by following the link at http://www.techmid.com/?p=114

Other useful references:

No comments:

Post a Comment