Liferay Tomcat Cluster+Session Replication

If you have multiple node and want to achieve session replication using jgroup cluster then please follow steps to achieve your goal.

Tomcat Node-I Configuration 

S1: Create tcp.xml(under tomcat/conf directory) and place below content
    Example
    
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="urn:org:jgroups"
        xsi:schemaLocation="urn:org:jgroups http://www.jgroups.org/schema/jgroups.xsd"
        >
        <TCP bind_port="4110"/>
        <TCPPING async_discovery="true" initial_hosts="${jgroups.tcpping.initial_hosts:NODE-I-IP-ONLY[4110],NODE-II-IP-ONLY[4110]}" port_range="0"/>
        <MERGE3  min_interval="10000" max_interval="30000"/>
        <FD_SOCK/>
        <FD_ALL timeout="9000" interval="3000" />
        <VERIFY_SUSPECT timeout="1500"  />
        <BARRIER />
        <pbcast.NAKACK2 use_mcast_xmit="false" discard_delivered_msgs="true"/>
        <UNICAST3 />
        <pbcast.STABLE stability_delay="1000" desired_avg_gossip="50000" max_bytes="4M"/>
        <pbcast.GMS print_local_addr="true" join_timeout="2000" view_bundling="true"/>
        <UFC max_credits="2M" min_threshold="0.4"/>
        <MFC max_credits="2M" min_threshold="0.4"/>
        <FRAG2 frag_size="60K" />
        <!--RSVP resend_interval="2000" timeout="10000"/-->
        <pbcast.STATE_TRANSFER/>
    </config>

S2: Update server.xml(under tomcat/conf directory) and add secure attribute into the connector tag as below
    <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" secure="true"/>
    
S3: Update server.xml(under tomcat/conf directory) and add jvmRoute attribute into the Engine tag as below
    <Engine name="Catalina" defaultHost="localhost" jvmRoute="node1">
    
S4: Update server.xml(under tomcat/conf directory) and add Cluster tag inside Engine tag as below
    <Engine name="Catalina" defaultHost="localhost" jvmRoute="node1">
        <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8" channelStartOptions = "3">
                <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.StaticMembershipService">
                        <LocalMember className="org.apache.catalina.tribes.membership.StaticMember" uniqueId="{1,3,5,7,8,0,0,2,0,0,1,0,0,0,0,9}"/>
                        <Member className="org.apache.catalina.tribes.membership.StaticMember" port="4110" host="NODE-II-IP-ONLY"  uniqueId="{9,3,5,7,8,0,0,2,0,0,1,0,0,0,0,1}" />
                    </Membership>
                   <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="auto" port="4110" autoBind="100" selectorTimeout="2000" 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.TcpPingInterceptor"/>
                   <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
                   <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor"/>
                   <Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/>

                   <Interceptor className="org.apache.catalina.tribes.group.interceptors.StaticMembershipInterceptor">
                        <Member className="org.apache.catalina.tribes.membership.StaticMember" port="4110" host="NODE-II-IP-ONLY" uniqueId="{9,3,5,7,8,0,0,2,0,0,1,0,0,0,0,1}" />
                   </Interceptor>
              </Channel>
              <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/>
              <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
              <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
        </Cluster>
        -------
        -------
    </Engine>

S5: Update web.xml(under tomcat/conf and tomcat/webapps/ROOT/WEB-INF directory) and add distributable tag before web-app tag end.
    <web-app>
        ----------
        ----------
        <distributable/>
    </web-app>

S6: Update portal-ext.properties(under liferay home directory) and add below additional props
    cluster.link.enabled=true
    cluster.link.channel.properties.control=${catalina.base}/conf/tcp.xml
    cluster.link.channel.properties.transport.0=${catalina.base}/conf/tcp.xml
    cluster.link.autodetect.address=${DB-HOST-URL}:${DB-PORT}
    portlet.session.replicate.enabled=true
    web.server.display.node=true
    
    Note: please change db-host-url and port as per application DB

S7: Update setenv.sh or setenv.bat(under tomcat/bin directory) and modify as below
    CATALINA_OPTS="$CATALINA_OPTS -Dfile.encoding=UTF-8  -Djgroups.bind_addr=NODE-I-IP-ONLY -Djgroups.tcpping.initial_hosts=NODE-I-IP-ONLY[4110],NODE-II-IP-ONLY[4110] -Djava.locale.providers=JRE,COMPAT,CLDR -Djava.net.preferIPv4Stack=true -Duser.timezone=GMT -server -Xms4096m -Xmx4096m -XX:MaxNewSize=1536m -XX:MaxMetaspaceSize=768m -XX:MetaspaceSize=768m -XX:NewSize=1536m -XX:SurvivorRatio=7"

S8: Now you can start tomcat first node server

Tomcat Node-II Configuration 

Amazon AWS Tomcat Cluster + Session Replication

-----------------------------------NODE-I CONFIGURATION END-----------------------------------

Tomcat-II Configuration
----------------------
S1: Create tcp.xml(under tomcat/conf directory) and place below content
    Example
    
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="urn:org:jgroups"
        xsi:schemaLocation="urn:org:jgroups http://www.jgroups.org/schema/jgroups.xsd"
        >
        <TCP bind_port="4110"/>
        <TCPPING async_discovery="true" initial_hosts="${jgroups.tcpping.initial_hosts:NODE-II-IP-ONLY[4110],NODE-I-IP-ONLY[4110]}" port_range="0"/>
        <MERGE3  min_interval="10000" max_interval="30000"/>
        <FD_SOCK/>
        <FD_ALL timeout="9000" interval="3000" />
        <VERIFY_SUSPECT timeout="1500"  />
        <BARRIER />
        <pbcast.NAKACK2 use_mcast_xmit="false" discard_delivered_msgs="true"/>
        <UNICAST3 />
        <pbcast.STABLE stability_delay="1000" desired_avg_gossip="50000" max_bytes="4M"/>
        <pbcast.GMS print_local_addr="true" join_timeout="2000" view_bundling="true"/>
        <UFC max_credits="2M" min_threshold="0.4"/>
        <MFC max_credits="2M" min_threshold="0.4"/>
        <FRAG2 frag_size="60K" />
        <!--RSVP resend_interval="2000" timeout="10000"/-->
        <pbcast.STATE_TRANSFER/>
    </config>

S2: Update server.xml(under tomcat/conf directory) and add secure attribute into the connector tag as below
    <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" secure="true"/>
    
S3: Update server.xml(under tomcat/conf directory) and add jvmRoute attribute into the Engine tag as below
    <Engine name="Catalina" defaultHost="localhost" jvmRoute="node2">
    
S4: Update server.xml(under tomcat/conf directory) and add Cluster tag inside Engine tag as below
    <Engine name="Catalina" defaultHost="localhost" jvmRoute="node2">
        <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8" channelStartOptions = "3">
                <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.StaticMembershipService">
                        <LocalMember className="org.apache.catalina.tribes.membership.StaticMember" uniqueId="{9,3,5,7,8,0,0,2,0,0,1,0,0,0,0,1}"/>
                        <Member className="org.apache.catalina.tribes.membership.StaticMember" port="4110" host="NODE-I-IP-ONLY"  uniqueId="{1,3,5,7,8,0,0,2,0,0,1,0,0,0,0,9}" />
                    </Membership>
                   <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="auto" port="4110" autoBind="100" selectorTimeout="2000" 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.TcpPingInterceptor"/>
                   <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
                   <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor"/>
                   <Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/>

                   <Interceptor className="org.apache.catalina.tribes.group.interceptors.StaticMembershipInterceptor">
                        <Member className="org.apache.catalina.tribes.membership.StaticMember" port="4110" host="NODE-I-IP-ONLY" uniqueId="{1,3,5,7,8,0,0,2,0,0,1,0,0,0,0,9}" />
                   </Interceptor>
              </Channel>
              <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/>
              <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
              <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
        </Cluster>
        -------
        -------
    </Engine>

S5: Update web.xml(under tomcat/conf and tomcat/webapps/ROOT/WEB-INF directory) and add distributable tag before web-app tag end.
    <web-app>
        ----------
        ----------
        <distributable/>
    </web-app>

S6: Update portal-ext.properties(under liferay home directory) and add below additional props
    cluster.link.enabled=true
    cluster.link.channel.properties.control=${catalina.base}/conf/tcp.xml
    cluster.link.channel.properties.transport.0=${catalina.base}/conf/tcp.xml
    cluster.link.autodetect.address=${DB-HOST-URL}:${DB-PORT}
    portlet.session.replicate.enabled=true
    web.server.display.node=true
    
    Note: please change db-host-url and port as per application DB

S7: Update setenv.sh/setenv.bat (under tomcat/bin directory) and modify as below
    CATALINA_OPTS="$CATALINA_OPTS -Dfile.encoding=UTF-8  -Djgroups.bind_addr=NODE-II-IP-ONLY -Djgroups.tcpping.initial_hosts=NODE-II-IP-ONLY[4110],NODE-I-IP-ONLY[4110] -Djava.locale.providers=JRE,COMPAT,CLDR -Djava.net.preferIPv4Stack=true -Duser.timezone=GMT -server -Xms4096m -Xmx4096m -XX:MaxNewSize=1536m -XX:MaxMetaspaceSize=768m -XX:MetaspaceSize=768m -XX:NewSize=1536m -XX:SurvivorRatio=7"

S8: Now you can start tomcat second node server

-----------------------------------NODE-II CONFIGURATION END-----------------------------------