Setting Up Session Replication in Tomcat With Liferay Portal

The purpose of this article is to setup a basic Tomcat cluster that has session replication. For true session replication, there must be a load balancer that redirects the traffic to the nodes. This article does not cover how to set up a load balancer. For information on how to set up a load balancer, refer to the vendor's documentation (e.g. Apache.).

This article also does not cover distributed caching or index replication, which are also necessary for clustering. Please refer to the article, Installing Liferay Portal in a Clustered Environment.

Make sure that all nodes have the same time and sync with NTP service.

Please note: This is not the only way to achieve session replication with Tomcat; other methods like memcached are also available.

Resolution

The following instructions will guide through the proper setup protocol.

1. In ${TOMCAT_HOME}/conf/server.xml add the jvmRoute value to the Engine section.

It will look something like this:

	<Engine name="Catalina" defaultHost="localhost" jvmRoute="worker1">

To clarify, "worker1" is the name assigned to it, and can be any alphanumeric value; for example: [a-z][A-Z][0-9][_\-]

If the Tomcat instances are running on the same machine, make sure the tcpListenPort attribute is unique for each instance. In most cases Tomcat is smart enough to resolve this on its own by auto-detecting available ports in the range 4000-4100. This is set in the server.xml.

2. Replace <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" /> with the following lines in the Engine:

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

	<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="4000"
		autoBind="100"
		selectorTimeout="5000"
		maxThreads="6"/>

	<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
	<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
	<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"/>
	</Channel>

	<Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/>
	<Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
	<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
		tempDir="/tmp/war-temp/"
		deployDir="/tmp/war-deploy/"
		watchDir="/tmp/war-listen/"
		watchEnabled="false"/>

	<ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
	<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
	</Cluster>

3. In ${TOMCAT_HOME}/webapps/ROOT/WEB-INF/web.xml add in the <distributable /> tag inside the <webapps> tag.

4. In ${APACHE_HOME}/conf/workers.properties, add in the worker information.

It should look something like this:

	worker.list=balancer
	worker.worker1.port=8009

	worker.worker1.host=${WORKER1_IP_ADDRESS/DOMAIN}
	
	worker.worker1.type=ajp13
	worker.worker1.lbfactor=1
	
	worker.worker2.port=8009

	worker.worker2.host=${WORKER2_IP_ADDRESS/DOMAIN}
	worker.worker2.type=ajp13
	worker.worker2.lbfactor=1
	
	worker.balancer.type=lb

	worker.balancer.balance_workers=worker1,worker2

	worker.loadbalancer.sticky_session=1

	worker.balancer.method=B

Please notice the use of "worker1" in the names. This is the same value as the jvmRoute value set in the first step. As stated previously, this value can be any alphanumeric value, but must remain consistent throughout the configuration.

If there are going to be more than 2 nodes, then create additional entries with the appropriate values, like "worker3", "worker4", etc...

5. In the portal-ext.properties file of the Liferay bundle, add the following:

	redirect.url.security.mode=domain
	web.server.display.node=true

Please note: The first property will allow things like AUI buttons to function with the Apache Server. The second property will make the node IDs visible as footers. These two properties are independent of session replication. Liferay Support assistance with further session replication configuration is limited.

6. Repeat the steps for the second node and all other nodes. Be sure to define the cluster settings in the portal-ext.properties; set the same database connections such that all nodes point to the same database. The choice of database is up to the user and Liferay can only give basic assistance in this matter.

7. Start servers sequentially. Cluster nodes cannot be started simultaneously because the process takes time to determine which node is the master node.

8. Start the load balancer Web Server.

9. Access the Web Server's IP Address or Domain Name. The web server will redirect the request to one node. Create a page, a user, or an asset.

10. Shut down one node. Verify that the traffic has redirected automatically to the second node, and that the page, user, and asset appear on the second node.

Notes

  • Session state is tracked by a cookie, so the URL must look the same from the outside, otherwise a new session will be created.
  • All session attributes must implement java.io.Serializable
  • If there are custom cluster valves defined, make sure the ReplicationValve is defined as well under the Cluster element in server.xml
  • The Cluster module uses the Tomcat JULI logging framework, so logging can be configured through the regular logging.properties file. To track messages, enable logging on the key: org.apache.catalina.tribes.MESSAGES

Additional Information

Was this article helpful?
0 out of 0 found this helpful