This blog post is intended to cover the changes in the TCP Unicast configuration with the updated version of JGroups plugin that’s shipped with Liferay DXP 7.2 SP1.

A clustered Liferay environment is normally needed for reliability and scalability; out of the box, a Liferay DXP 7.2 clustered environment uses UDP Multicast for clustering traffic. While UDP Multicast clustering is optimal from a network performance standpoint, there are a few issues with it. There’s a possibility that multiple divergent environments without LAN separation can communicate with each other causing unexpected interactions in the environment. In addition, UDP Multicast traffic is generally disabled in most public cloud environments, and as it is a very “chatty” protocol, it is common practice for enterprises to disable it on most network segments as well. As a result, in most situations, XTIVIA recommends using TCP Unicast for Liferay cluster communications.

This post covers the steps required to setup TCP Unicast clustering in Liferay DXP 7.2 EE environments. The same instructions apply to on-premises or hosted Enterprise infrastructure, Azure, and AWS platforms. Throughout this blog, common locations have been abstracted out as variable names; this is to maintain a sense of brevity throughout the document. These variables do not have any meaning outside of the document itself. Example variables include: $host1_FQDN, $name_of_the_s3bucket, $AWS_access_key, $AWS_secret_key.

Configure TCP Unicast clustering for Liferay

To implement TCP Unicast clustering for a Liferay environment, the following steps need to be performed in all the Liferay instances that belong to the target cluster.

Step 1. Ensure that ports are open

For Liferay clustering to be successful, the hosts need to be able to communicate with each other to send clustering packets across the network. For our example, we will use port 7800 for TCP Unicast clustering in Liferay. We have provided two example configurations; one using static TCP hostnames and one using a dynamic list of hosts maintained in an AWS S3 bucket to maintain the cluster state for Liferay clustering. Other options for maintaining the Liferay clustering state include using a shared network or cluster filesystem or using a JDBC datasource.

Step 2. Configure TCP Unicast

Create a TCP Unicast file

For the next step, an XML file (for simplicity, we’re naming it dxp-clustering.xml) containing the TCP Unicast configuration should be created. Please note that we recommend the file be copied to the global library filesystem location for the Java Application Server so that the file can be read by the Liferay application on startup. With Liferay DXP 7.2 SP1, Liferay ships with a newer version of the JGroups library. The following configuration file covers the updated configuration required for a successful initialization. Please note that we have included the TCP_PING, S3_PING, and JDBC_PING discovery protocols as comments in this example. The following example uses FILE_PING as the cluster member discovery mechanism. It’s highly recommended to use a location on the shared filesystem hosting the Liferay documents and media library location as the location for the cluster membership registry as illustrated in this example.

<!--
    TCP based stack, with flow control and message bundling. This is usually used when IP
    multicasting cannot be used in a network, e.g. because it is disabled (routers discard multicast).
    Note that TCP.bind_addr and TCPPING.initial_hosts should be set, possibly via system properties, e.g.
    -Djgroups.bind_addr=192.168.5.2 and -Djgroups.tcpping.initial_hosts=192.168.5.2[7800]
    author: Bela Ban
-->
<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="7800"
         recv_buf_size="${tcp.recv_buf_size:5M}"
         send_buf_size="${tcp.send_buf_size:640K}"
         max_bundle_size="64K"
         sock_conn_timeout="300"

         thread_pool.enabled="true"
         thread_pool.min_threads="0"
         thread_pool.max_threads="20"
         thread_pool.keep_alive_time="30000"

         />
                         
<!--        <TCPPING async_discovery="true"
             initial_hosts="${jgroups.tcpping.initial_hosts:localhost[7800],localhost[7801]}"
             port_range="2"/>
-->
<!-- <JDBC_PING
connection_url="jdbc:mysql://[DATABASE_IP]/[DATABASE_NAME]?useUnicode=true&characterEncoding=UTF-8&useFastDateParsing=false"
    connection_username="[DATABASE_USER]"
    connection_password="[DATABASE_PASSWORD]"
    connection_driver="com.mysql.jdbc.Driver"/> -->

<!--  <JDBC_PING
   datasource_jndi_name="java:comp/env/jdbc/LiferayPool"/> -->



<!--	<S3_PING location="$name_of_the_s3bucket" 
			access_key="$AWS_access_key"
			secret_access_key="$AWS_secret_key" 
			timeout="2000"
			num_initial_members="2"/> -->


    <FILE_PING location="/liferay/shared/document/library/jgroups" />

       <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="3000"
                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>

Step 3. Add properties to portal-ext.properties

For Liferay to use TCP Unicast clustering, the following properties need to be included in the portal-ext.properties file. Please note that we recommend setting the cluster link autodetect address to the Liferay database host and port; this overrides the standard Liferay value, which uses www.google.com:80 for this purpose. The assumption we make here is that the database host is always available and can be used by Liferay instances to accurately determine the network interface to use for clustering purposes.

cluster.link.enabled=true                cluster.link.autodetect.address=database_host:port
cluster.link.channel.properties.control=dxp-clustering.xml
cluster.link.channel.properties.transport.0=dxp-clustering.xml

Step 4: Restart Liferay and verify

To verify that clustering is working as expected, you can take a look at the Liferay logs. The logs should contain lines similar to the following, showing successful cluster initialization:

INFO [localhost-startStop-1][ClusterBase:142] Autodetecting JGroups outgoing IP address
and interface for $database_host:port
INFO [localhost-startStop-1][ClusterBase:158] Setting JGroups outgoing IP address to
172.31.42.34 and interface to eth0
-------------------------------------------------------------------
GMS: address=ip-172-31-42-34-20199, cluster=LIFERAY-CONTROL-CHANNEL, physical
address=172.31.42.34:7800
-------------------------------------------------------------------
-------------------------------------------------------------------
GMS: address=ip-172-31-42-34-39646, cluster=LIFERAY-TRANSPORT-CHANNEL-0, physical
address=172.31.42.34:7800
-------------------------------------------------------------------

And lines similar to the following showing successful connectivity between the cluster members:

INFO  [localhost-startStop-1][BaseReceiver:64] Accepted view [ip-172-31-35-224-26939|11]
[ip-172-31-35-224-26939, ip-172-31-42-34-39646]

Alternatively, you can make changes to a web content article or page on one instance of the cluster and verify if the changes are replicated on the other members of the cluster.

Other Ping mechanisms for cluster discovery

JGroups supplies other means for cluster members to discover each other, including Rackspace Ping, BPing, File Ping, and more. Please see the JGroups Documentation for information about these discovery methods.

Summary

Leveraging JGroups for TCP Unicast clustering offers a wide variety of choices for reliable clustering mechanisms in a Liferay DXP 7.2 environment. With Liferay’s clustering mechanism, you have the tools you need to scale your Liferay environment effortlessly.

If you have questions on how you can best leverage our expertise or need help with your Liferay DXP implementation, please engage with us via comments on this blog post, or reach out to us at here.

Additional Reading

You can also continue to explore Liferay DXP by checking out The Top 10 New Features in Liferay DXP 7.2 from a functional perspective, or Planning Liferay DXP 7.2 upgrade for a comprehensive blog post on items to consider while upgrading to Liferay DXP 7.2. You can also check out Liferay DXP 7.2 Content Pages Primer from a content creation perspective, or Top 5 DevOps Features in Liferay DXP from a devops perspective.

Share This