Configuring HA-JMS on JBoss server cluster

After setting up the HTTP/HTTPS configuration for JBoss server cluster, the next assignment on my table was to set up the HA-JMS on the server cluster.

My JBoss installation folder structure is as below:
JBOSS_HOME\server\all
JBOSS_HOME\server\default
JBOSS_HOME\server\minimal
The “all” folder has everything configured for HA, however to understand the process, I have set up HA JMS within default folder. Go to the following folder JBOSS_HOME\server\default\deploy\jms
Remove all the files within the jms folder except jms-ra.rar. Please take a backup of these files some files might be required later. Within the default folder create a new folder named deploy-hasingleton within this folder create a sub-folder named jms. The contents of this folder will be similar to contents of the jms folder we had cleaned up earlier. The contents are as follows:
Folder - jbossmq-httpil.sar
File - hsqldb-jdbc-state-service.xml
    No change from the default file except change the following tag
    <depends optional-attribute-name="ConnectionManager">jboss.jca:service=DataSourceBinding,name=MySqlDS</depends>
    My data source name is MySqlDS, please point to your appropriate data source name.
File - jbossmq-destinations-service.xml
    I have retained the original file please feel free alter this file to 
reflect your queues/topics.
File - jbossmq-service.xml
    No change
File - jms-ds.xml
    No change
File - jvm-il-service.xml
    No change
File - mysql-jdbc2-service.xml
    Change the following tag to point to the correct data source
    <depends optional-attribute-name="ConnectionManager">jboss.jca:service=DataSourceBinding,name=MySqlDS</depends>
File - uil2-service.xml No change
Check if the JBOSS_HOME\server\default\lib has the following two jars: jbossha.jar, jgroups.jar. If not add them from the JBOSS_HOME\server\all\lib folder.
Open the login-config.xml file from the folder JBOSS_HOME\server\default\conf.
Search for the following tag:
<!-- Security domain for JBossMQ -->
    <application-policy name = "jbossmq">
       <authentication>
          <login-module code = "org.jboss.security.auth.spi.DatabaseServerLoginModule"
             flag = "required">
             <module-option name = "unauthenticatedIdentity">guest</module-option>
             <module-option name = "dsJndiName">java:/MySqlDS</module-option>
             <module-option name = "principalsQuery">SELECT PASSWD FROM JMS_USERS WHERE USERID=?</module-option>
             <module-option name = "rolesQuery">SELECT ROLEID, 'Roles' FROM JMS_ROLES WHERE USERID=?</module-option>
          </login-module>
       </authentication>
    </application-policy>
And change the dsJndiName to correct data source. Ensure that the name retains java:/ portion.
Copy cluster-service.xml and deploy-hasingleton-service.xml in the JBOSS_HOME\server\default\deploy folder. The sample files are available in JBOSS_HOME\all\default\deploy folder. In my case both the instances are deployed on the same machine, therefore you might need to change the port numbers in the cluster-service.xml.
Configure your datasource. I have created mysql-ds.xml remove the hsqldb-ds.xml file. Sample files for different types of databases are available at JBOSS_HOME\docs\jca directory.
 
Now start the two instances. In case, the deployment is correct, during startup of the first instance you will see the following statements in the log files: 
-------------------------------------------------------
GMS: address is 122.22.22.22:3576
-------------------------------------------------------
2009-04-21 17:52:58,419 DEBUG [org.jboss.ha.framework.interfaces.HAPartition.DefaultPartition] ViewAccepted: initial members set
2009-04-21 17:52:58,435 DEBUG [org.jboss.ha.framework.server.ClusterPartition] Starting channel
2009-04-21 17:52:58,435 DEBUG [org.jboss.ha.framework.interfaces.HAPartition.DefaultPartition] get nodeName
2009-04-21 17:52:58,435 DEBUG [org.jboss.ha.framework.interfaces.HAPartition.DefaultPartition] Get current members
2009-04-21 17:52:58,435 INFO  [org.jboss.ha.framework.interfaces.HAPartition.DefaultPartition] Number of cluster members: 1
2009-04-21 17:52:58,435 INFO  [org.jboss.ha.framework.interfaces.HAPartition.DefaultPartition] Other members: 0
2009-04-21 17:52:58,435 INFO  [org.jboss.ha.framework.interfaces.HAPartition.DefaultPartition] Fetching state (will wait for 30000 milliseconds):
And in the second instance startup, the following logs are
created:
-------------------------------------------------------
GMS: address is 122.22.22.22:3589
-------------------------------------------------------
2009-04-21 17:55:51,780 DEBUG [org.jboss.ha.framework.interfaces.HAPartition.DefaultPartition] ViewAccepted: initial members set
2009-04-21 17:55:51,780 DEBUG [org.jboss.ha.framework.server.ClusterPartition] Starting channel
2009-04-21 17:55:51,780 DEBUG [org.jboss.ha.framework.interfaces.HAPartition.DefaultPartition] get nodeName
2009-04-21 17:55:51,780 DEBUG [org.jboss.ha.framework.interfaces.HAPartition.DefaultPartition] Get current members
2009-04-21 17:55:51,780 INFO  [org.jboss.ha.framework.interfaces.HAPartition.DefaultPartition] Number of cluster members: 2
2009-04-21 17:55:51,780 INFO  [org.jboss.ha.framework.interfaces.HAPartition.DefaultPartition] Other members: 1
2009-04-21 17:55:51,780 INFO  [org.jboss.ha.framework.interfaces.HAPartition.DefaultPartition] Fetching state (will wait for 30000 milliseconds):
2009-04-21 17:55:51,811 DEBUG [org.jboss.ha.framework.interfaces.HAPartition.DefaultPartition] setState called
You can use a sample JMS client to insert messages in queue. You can verify that only one queue is created on the cluster and if the master server fails, the backup server will create the queue. The JMS client application will however need to know both the JNDI URLs i.e for the master and the slave. That intelligence will need to be built in by the developer. Please find below my JNDI client and jndi.properties file for your ready reference.
JNDI properties file contents:
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=jnp://localhost:2099
##java.naming.provider.url=jnp://localhost:1199
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces

JNDI client contents:

package com.jms.test;

import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.NamingException;

public class JNDIClient {

	public static void main(String[] args) {
		// create a new intial context, which loads from jndi.properties file
		javax.naming.Context ctx;
		try {
			ctx = new javax.naming.InitialContext();
			// lookup the connection factory
			javax.jms.QueueConnectionFactory factory
				= (javax.jms.QueueConnectionFactory)ctx.lookup("ConnectionFactory");

			// create a new TopicConnection for pub/sub messaging
			QueueConnection conn = factory.createQueueConnection();
			Queue queue = (Queue)ctx.lookup("queue/A");

			Session session = conn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
			MessageProducer producer = session.createProducer(queue);
			TextMessage msg = session.createTextMessage();
			msg.setStringProperty("Name", "Cooler Dude");
			producer.send(queue, msg);

			session.close();
			conn.close();

		} catch (NamingException e) {
			e.printStackTrace();
		} catch (JMSException e) {
			e.printStackTrace();
		}

	}
}
The jndi.properties file should be placed on the JBoss server classpath.
Advertisements

One thought on “Configuring HA-JMS on JBoss server cluster

  1. Thank you for this article, i’m using jboss 4.0.5 <ho deploy my application. My cluster is about 2 nodes for example.
    I've read that its better to disable JMS Queue for better performances, but in clutered mode I don't know?
    What do you think about that?
    Thanks.
    Sorry for my english

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s