The following sections give you information and instructions on how to cluster the message broker profile of WSO2 EI.
The clustering deployment pattern
This pattern has two WSO2 EI nodes to serve service requests with high availability and scalability. The following image depicts the sample pattern this clustering deployment scenario will follow.
This pattern uses two nodes as well-known members . It is always recommended to have all nodes of the cluster as well-known members.
When configuring your WSO2 products for clustering to host them in your production environment, it is necessary to use a specific IP address and not localhost or host names in your configurations.
Creating the databases
All profiles of WSO2 EI uses a database to store information such as user management details and registry data. All nodes in the cluster must use one central database for config and governance registry mounts. You can create the following databases and associated datasources.
|JDBC user store and authorization manager|
|Shared database for config and governance registry mounts in the product's nodes|
|Local registry space in Node 1|
|Local registry space in Node 2|
It is recommended to use an industry-standard RDBMS such as Oracle, PostgreSQL, MySQL, MS SQL, etc. for most enterprise testing and production environments. However, you can also use the embedded H2 database only for the
Following the steps below to create the databases necessary.
These instructions assume you are installing MySQL as your relational database management system (RDBMS), but you can install another supported RDBMS as needed.
Download and install MySQL Server.
Download the MySQL JDBC driver.
Download and unzip the WSO2 EI binary distribution.
Throughout this guide,
<EI_HOME>refers to the extracted directory of the WSO2 EI product distribution.
- Unzip the downloaded MySQL driver, and copy the MySQL JDBC driver JAR (
mysql-connector-java-x.x.xx-bin.jar) into the
<EI_HOME>/lib/directory of both WSO2 EI nodes.
Add the following line to the
/etc/hostsfile to define the hostname for configuring permissions for the new database:
Do this step only if your database is not on your local machine and on a separate server.
- Execute the following command in a terminal/command window, where username is the username you want to use to access the databases: mysql
-u username -p
Specify the password to access the databases with the username you specified when prompted.
Create the databases using the following commands:
About using MySQL in different operating systems
For users of Microsoft Windows, when creating the database in MySQL, it is important to specify the character set as latin1. Failure to do this may result in an error (error code: 1709) when starting your cluster. This error occurs in certain versions of MySQL (5.6.x) and is related to the UTF-8 encoding. MySQL originally used the latin1 character set by default, which stored characters in a 2-byte sequence. However, in recent versions, MySQL defaults to UTF-8 to be friendlier to international users. Hence, you must use latin1 as the character set as indicated below in the database creation commands to avoid this problem. Note that this may result in issues with non-latin characters (like Hebrew, Japanese, etc.). The following is how your database creation command should look.
mysql> create database <DATABASE_NAME> character set latin1;
For users of other operating systems, the standard database creation commands will suffice. For these operating systems, the following is how your database creation command should look.
mysql> create database <DATABASE_NAME>;
Create and configure the following database, which is specific to the message broker profile using the following commands:
|Stores instance data that are specific to the message broker profile|
<EI_HOME>, username and password are the same as those you specified in the previous steps.
Mounting the registry
Add the following configurations to the
REGISTRY_DB database) mounts on both WSO2 EI nodes.
Note the following when adding these configurations:
- The existing
wso2registrymust not be removed.
- The datasourceyouspecifyin the
<dbConfig name="sharedregistry">tag must match the JNDI Config name you specify in the
The registry mount path denotes the type of registry. For example, ”
/_system/config” refers to configuration Registry, and "
/_system/governance" refers to the governance registry.
<dbconfig>entry enables you to identify the datasource you configured in the
.xml file. The unique name "sharedregistry" referstothatdatasource entry.
<remoteInstance>section refers to an external registry mount. Specify the read-only/read-write nature of this instance, caching configurations and the registry root location in this section.
Also, specify the cache ID in the
<remoteInstance>section. This enables caching to function properly in the clustered environment.
Cache ID is the same as the JDBC connection URL of the registry database. This value is the Cache ID of the remote instance. It should be in the format of
[email protected]$database_url, where
$database_usernameis the username of the remote instance database and
$database_urlis the remote instance database URL. This cacheID denotes the enabled cache. In this case, the database it should connect to is
REGISTRY_DB, which is the database shared across all the nodes. You can find that in the mounting configurationsofthesamedatasource that is being used.
Define a unique name in the
<id>tag for each remote instance. This is then referred to from mount configurations. In the above example, the unique ID for the remote instance is "
Specify the actual mount path and target mount path in each of the mounting configurations. The target path can be any meaningful name. In this instance, it is "
Configuring a message broker profile node
It is vital to synchronize time across all the Broker nodes in the cluster to make them function properly.
Do the following configurations for all nodes of your cluster.
Configure the datasourcesto point to the
WSO2_USER_DBdatabases as follows in the
.xml file as follows:
Replace the username, password, and database URL of your MySQL environment accordingly.
Repeat this configuration on the second WSO2 EI node to configure the datasourcesto point to the
WSO2_USER_DBdatabases as follows: (Change the username, password, and database URL as needed for your environment):
Add the following configuration in the
<EI_HOME>/wso2/broker/conf/user-mgt.xml file to configure the user stores.
Enter the datasource information for the user store that you configured in the
.xml file. You can change the admin username and password as well. However, you should do this before starting the server.
Remove or uncomment the default H2-based WSO2_MB_STORE_DB following configuration in the
Uncomment or add the following
WSO2_MB_STORE_DBconfiguration in the
<EI_HOME>/wso2/broker/conf/datasources/master-datasources.xmlfile based on your DBMS type.
Update the JDBC URL to correctly point to your database and enter the username and password for your database user with the proper permissions.
Uncomment or add the following configuration in the
<EI_HOME>/wso2/broker/conf/broker.xmlfile. (Enter the message store based on your database type and Andes context store).
<EI_HOME>/wso2/broker/conf/axis2/axis2.xmlfile as follows to set up the cluster configurations.
- Enable clustering for this node as follows:
<clustering class="org.wso2.carbon.core.clustering.hazelcast.HazelcastClusteringAgent" enable="true">
- Set the membership scheme to "wka" to enable the well-known address registration method. (This node sends cluster initiation messages to the WKA members):
- Specify the name of the cluster this node will join as folows:
- Specify the host to communicate cluster messages as follows:
Specify the port to communicate cluster messages as follows:
This port number is not affected by the port offset value specified in the
xmlfile. If this port number is already assigned to another server, the clustering framework automatically increments this port number. However, if there are two servers running on the same machine, ensure that a unique port is set for each server.
Specify the well-known members as follows: (The port value for the WKA node must be the same value as it's localMemberPort (in this case it is 4100).
You can also use IP address ranges for the hostname (e.g., 192.168.1.2-10). However, you can define a range only for the last portion of the IP address. Smaller the range, the faster the time it takes to discover members since each node has to scan a lesser number of potential members. The best practice is to add all the members (including itself) in all the nodes to avoid any conflicts in configurations.
- Enable clustering for this node as follows:
Add the following thrift-related configurations in the
This file is the root configuration file of brokering. Do the changes you do to this file in all the broker profile nodes. Configure the
thriftServerHostvalue to point to the IP address of the message broker profile node.
Follwingaredetails on these configurations.
This configuration is related to brokering thrift communications.
In a clustered deployment, an ID is assigned to each brokering node via the cluster node identifier. This element can be used to override the cluster node identifier for this brokering node. If the value for this element is left as
default, the default node ID is generated using the IP and a universally unique identifier (UUID). The node ID of each member in a cluster must be unique.
This is a sub-element of the
<coordination>tag. WSO2 EI uses Apache Thrift for communications relating to message delivery. Therefore, an Apache Thrift server is started in each brokering node in a clustered deployment. This element should point to the IP address of the Apache Thrift server. This should point to the IP address of the brokering node that hosts the thrift server. The default value for this is
localhost. For example, if you are configuring a brokering node hosted in 192.168.0.102 as the thrift server, this value should be 192.168.0.102.
This is another sub-element of the
<coordination>tag. This should point to the port of the thrift server in the message broker profile. The default port is 7611. It is recommended to use this port for all broker nodes in your cluster.
This is used to handle half-open TCP connections between the broker nodes in a cluster. In such situations, the socket may need to have a timeout value to invalidate the connection (in milliseconds). A timeout of zero is interpreted as an infinite timeout. Be sure to set this value to 180000 milliseconds as shown below.
Enable heartbeat messaging for each of the broker nodes by following the steps given below. This is required for handling TCP connections between the broker nodes and client systems (publishers and subscribers).
What is heartbeat messaging?
When a client is connected to the broker, both the broker and the client should be able to detect problem situations where the TCP connection is half open or where the connecting client/broker is unresponsive. This can be achieved by enabling heartbeat messaging between the broker and the client.
The heartbeat messaging configuration allows both the broker and the client to verify whether the connection is inactive or whether the connecting system (broker or client) is inactive by periodically sending messages to each other.
For example, you can set the heartbeat delay time to 30 seconds. This means that if the broker (or the client) does not receive the expected response from the other system within 30 seconds, it will send a heartbeat message to check if the connection is inactive or if the other system is inactive. If the connection is inactive or is half-open, there will be a clear indication of connection failure. However, if the connection is active but the other system is unresponsive, the broker or the client will continue to send heartbeat messages (every 30 seconds). By default, the broker and clients are configured to terminate (timeout) the connection after sending two heartbeat messages; however, this time out configuration can be changed.
Note: In a scenario where the subscriber client is sending the heartbeat message to the broker node, if the connection is found to be broken or if the broker node is inactive, the connection will failover to another broker node in the cluster.
- Open the qpid
-config.xmlfile that is stored in the
Set the heartbeat delay as shown below. The recommended heartbeat delay is 30 seconds.
The elements in the above configuration are explained below.
delay The <delay> element specifies the time interval between heartbeat messages. This is the time that the broker or client will wait to receive a response from the other party. If the response is not received within this time, a heartbeat message is triggered. timeoutFactor The number of heartbeat messages the broker will send to the client before terminating the connection. That is, if the timeoutFactor is 2, the broker will send heartbeat messages every 30 seconds twice, and if a response is not received from the client, the connection will be terminated.
- Open the qpid
Configuring Hazelcast properties
WSO2 products use Hazelcast as its default clustering engine. You can configure the hazelcast properties for the product nodes by following the steps given below.
Add the following property configurations to the
hazelcast.propertiesfile stored in the
The above configurations are explained below.
- Hazelcast shutdown hook: This configuration disables the shutdown hook in hazelcast, which ensures that the hazelcast instance shuts down gracefully whenever the product node shuts down. If the hazelcast shutdown hook is enabled (which is the default behavior of a product), you will see errors such as "Hazelcast instance is not active!" at the time of shutting down the product node: This is because the hazelcast instance shuts down too early when the shutdown hook is enabled.
- Hazelcast logging type: This configuration sets the hazelcast logging type to log4j, which allows hazelcast logs to be written to the
If you have enabled log4j for hazelcast logging as explained above, be sure to enter the configuration shown below in the
log4j.propertiesfile (stored in the
<EI_HOME>/wso2/broker/conf/directory). This can be used to configure the log level for hazelcast logging. For a clustered production environment, it is recommended to use INFO as the log level as shown below.
Configuring cluster coordination
The Messgae Broker profile in WSO2 EI introduces cluster coordination through an RDBMS. This means that the coordination between the nodes in a cluster can be managed through an RDBMS, just as message persistence. Therefore, the RDBMS that is connected to the MB nodes in the cluster is, by default, used for message persistence as well as cluster coordination. Shown below is the configuration in the
broker.xml file (stored in the
<EI_HOME>/wso2/broker/conf/ directory), which enables RDBMS-based cluster coordination. If required, you can disable the following configuration, which will allow the hazelcast engine to manage cluster coordination. However, note that you need to configure the cluster to handle network partitioning when hazelcast-based cluster coordination is used.
Handling network partitioning in Hazelcast-based clustering
Network partitioning in the network used for cluster coordination can sometimes disrupt the cluster. The Message Broker profile of WSO2 EI introduces a new configuration to handle network partitioning that may occur when cluster coordination is managed by the hazelcast engine (as opposed to the RDBMS as explained above).
For example, consider a cluster of three MB nodes that uses two separate networks for cluster coordination and message persistence. The network with the RDBMS will persist messages, subscriptions and queues etc., and the cluster network communicates information about subscriptions, queue additions, and to decide on the coordinator of the cluster. If one of the nodes in the cluster disconnects from the network used for cluster coordination, that node will separate from the cluster and function as a separate node/cluster (separate partition). That is, the three-node cluster will now be working as two separate clusters. However, the disconnected node will still be up and running, and message persistence will continue uninterrupted through the message persistence network. This will cause inconsistencies in the system because message persistence and cluster coordination will not be synchronized. In such a situation, it is necessary to stop the disconnected node from accepting messages.
The above situation can be prevented in the Message Broker profile by configuring the minimum node count of the cluster. For example, if the cluster size is 5 and we have configured the minimum node count to 3 nodes, during a network partition (or when nodes crash or shut down) any partition that has 3 or more nodes will keep functioning, while the other partitions will stop processing messages.
Follow the steps given below to enable this feature.
<EI_HOME>/wso2/broker/repository/conf/broker.xmlfile and set the
<networkPartitionsDetection>element shown below to
enabled="true". Note that this configuration is disabled by default as shown below.
- Update the
<minimumClusterSize>property in the above configuration to specify the minimum node count the cluster should maintain in order to operate. Note that if this value should be at least two for cluster coordination to work. If the number of nodes in the cluster becomes less that configured value, the cluster will not accept any incoming traffic. That is, all subscriptions will be disconnected.
Testing the cluster
Follow the steps below to test the cluster.
Restart the configured load balancer.
Deploy artifacts to each product deployment location.
Use a deployment synchronization mechanism to synchronize the artifacts in the
<EI_HOME>/wso2/broker/repository/deployment/directory. Always deploy artifacts first to the WSO2 EI server profile node with the registry configured as read/write. Next, deploy the artifacts to the other nodes.
- Execute the following command and start both WSO2 EI nodes:
Check for ‘member joined’ log messages in all consoles.
Additional information on logs and new nodes
When you terminate one node, all nodes identify that the node has left the cluster. The same applies when a new node joins the cluster. If you want to add another new node, copy existing node without any changes if you are running it on a new server (such as xxx.xxx.xxx.184). If you intend to use the new node on a server where another WSO2 product is running, use a copy of node and change the port offset accordingly in the
<EI_HOME>/wso2/broker/conf/carbon.xmlfile. You also have to change
<EI_HOME>/wso2/broker/conf/axis2/axis2.xml file if that product has clustering enabled. Also, map all hostnames to the relevant IP addresses when creating a new node. The log messages indicate if the new node joins the cluster.
- Access the Management Console through the LB using the following URL:
- Test load distribution via the following URLs:
Add a sample proxy service with the log mediator in the inSequence so that it will display logs in the terminals, and then observe the cluster messages sent.
Send a request to the endpoint through the load balancer to verify that the proxy service is activated only on the active node(s) while the nodes remain passive. This is to test that the load balancer manages the active and passive states of the nodes, activating nodes as needed and leaving the rest in passive mode. For example, you would send the request to the following URL: http
Tuning performance of the cluster
Follow the steps below to tune performance of the cluster:
The below example parameter values might not be the optimal values for the specific hardware configurations in your environment. Therefore, it is recommended to carry out load tests on your environment to tune the load balancer and other configurations accordingly.
- Change the following default memory allocation settings for the server node and the JVM tuning parameters in the server startup scripts (i.e., the
<EI_HOME>/bin/broker.batfile) according to the expected server load:
-Xms256m -Xmx1024m -XX:MaxPermSize=256m
Modify important system files, which affect all programs running on the server. It is recommended to familiarize yourself with these files using Unix/Linux documentation before editing them.