One of the primary motivations for setting up Liferay in a cluster is to provide high availability in the event of an application server crash. In this post, I will run through the process of configuring Tomcat to provide basic session replication, which is a critical aspect of high availability; session replication allows a second Tomcat server to service requests for users whose sessions were originally created on a different Tomcat instance in the cluster.

For the purposes of this entry, it is assumed that the reader is familiar with basic Tomcat clustering configuration.

server.xml Configuration Changes

There are two changes that need to be made to the Tomcat server.xml file in order to support clustering; the addition of a ClusterSessionListener to the <Cluster /> configuration container, and the addition of a timeout attribute to the <Transport /> entity defined in the <Channel /> configuration container.

Addition of the timeout attribute to the <Sender /> is quite simple; just identify the following section in server.xml:

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

Change this line to the following:

<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter"> <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender" timeout="30000" /> </Sender>

This change will tell the cluster to wait for 30 seconds before timing out message requests to the cluster; the default value for this attribute is 3000, or 3 seconds.

The ClusterSessionListener is defined as an entity appearing at the end of the <Cluster /> configuration container; simply insert the following line prior to the closing </Cluster> tag in server.xml:

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

context.xml Configuration Changes

The change to the context.xml file located in ${CATALINA_HOME}/conf is a simple one; simply identify the line below:

<Context>

and change it as follows:

<Context distributable="true">

web.xml Configuration Changes

Each web application deployed within Liferay needs to have its web.xml file changed to support session replication; luckily, the change is a small one. Simply add the <distributable/> tag to the beginning of each web.xml file as follows:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="[http://java.sun.com/xml/ns/j2ee"] 
   xmlns:xsi="[http://www.w3.org/2001/XMLSchema-instance"]
   xsi:schemaLocation="[http://java.sun.com/xml/ns/j2ee] 
   [http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"] 
   version="2.4"
>
    <distributable/>
    <!-- ignore details -->
</web-app>

Note that this means that any and all objects being stored on the session MUST implement the java.io.Serializable interface.

Additional Configuration Changes

One of the tricky aspects of this is that once the cluster is started up, additional Tomcat nodes are no longer able to load their portal-ext.properties file from the default location in ${CATALINA_HOME}/webapps/ROOT/WEB_INF/classes. Obviously, this presents a rather significant problem, as Liferay will then start up with the default values from portal.properties in portal-impl.jar. To get around this problem, simply create a symlink to ${CATALINA_HOME}/webapps/ROOT/WEB_INF/classes/portal-ext.properties in the ${CATALINA_HOME}/lib directory for each Tomcat instance. It is also possible to copy the file directly, but for maintenance purposes, a symlink is preferable.

That’s it; your Tomcat instances should now be actively replicating session information across the TCP channel defined in server.xml. Note that this type of session replication can have a negative impact on performance in larger cluster environments; in those situations, it’s better to configure the application server to persist and retrieve session information from a central store, or segment out cluster replication such that only a subset of application server instances actively store and maintain individual session information.

Share This