JBoss Messaging JMS Client Side Load-Balancing Example


This example demonstrates how subsequent connections created from a JMS Connection Factory can be created to different nodes of the cluster. In other words it demonstrates how JBoss Messaging does client side load balancing of connections across the cluster.

The particular load-balancing policy can be chosen to be random, round-robin or user-defined. Please see the user guide for more details of how to configure the specific load-balancing policy. In this example we will use the default round-robin load balancing policy.

The list of servers over which JBoss Messaging will round-robin the connections can either be specified explicitly in the connection factory when creating it, or deploying it on the server, or the factory can be configured to use UDP discovery to discover the list of servers over which to round-robin. This example will use UDP discovery to obtain the list.

This example starts three servers which all broadcast their location using UDP discovery. The UDP broadcast configuration can be seen in the jbm-configuration.xml file.

A JMS ConnectionFactory is deployed on each server specifying the discovery group that will be used by that connection factory.

For more information on JBoss Messaging load balancing, and clustering in general, please see the clustering section of the user manual.

Example step-by-step

To run the example, simply type ant from this directory


  1. Get an initial context for looking up JNDI from server 0.
  2.            
       initialContext = getContext(0);
       
            
  3. Look-up the JMS Queue object from JNDI
  4.            Queue queue = (Queue)initialContext.lookup("/queue/exampleQueue");
            
  5. Look-up a JMS Connection Factory object from JNDI on server 0
  6.            ConnectionFactory connectionFactory = (ConnectionFactory)initialContext.lookup("/ConnectionFactory");
            
  7. We create three connections, since we are using round-robin load-balancing this should result in each connection being connected to a different node of the cluster
  8.            
            connectionA = connectionFactory.createConnection();
             
            connectionB = connectionFactory.createConnection();
             
            connectionC = connectionFactory.createConnection();
               
            
  9. We create a JMS Session on each of those connections
  10.            
            Session sessionA = connectionA.createSession(false, Session.AUTO_ACKNOWLEDGE);
             
            Session sessionB = connectionB.createSession(false, Session.AUTO_ACKNOWLEDGE);
             
            Session sessionC = connectionC.createSession(false, Session.AUTO_ACKNOWLEDGE);
               
            
  11. We start the connections to ensure delivery occurs on them
  12.           
            connectionA.start();
    
            connectionB.start();
             
            connectionC.start();
              
            
  13. We create JMS MessageConsumer objects on the sessions
  14.           
             MessageConsumer consumerA = sessionA.createConsumer(queue);
             
             MessageConsumer consumerB = sessionB.createConsumer(queue);
             
             MessageConsumer consumerC = sessionC.createConsumer(queue);
              
            
  15. We create JMS MessageProducer objects on the sessions
  16.            
            MessageProducer producerA = sessionA.createProducer(queue);
             
            MessageProducer producerB = sessionB.createProducer(queue);
             
            MessageProducer producerC = sessionC.createProducer(queue);
               
            
  17. We send some messages on each producer
  18.            
             final int numMessages = 10;
    
             for (int i = 0; i < numMessages; i++)
             {
                TextMessage messageA = sessionA.createTextMessage("A:This is text message " + i);
    
                producerA.send(messageA);
    
                System.out.println("Sent message: " + messageA.getText());
                
                TextMessage messageB = sessionB.createTextMessage("B:This is text message " + i);
    
                producerB.send(messageB);
    
                System.out.println("Sent message: " + messageB.getText());
                
                TextMessage messageC = sessionC.createTextMessage("C:This is text message " + i);
    
                producerC.send(messageC);
    
                System.out.println("Sent message: " + messageC.getText());            
             }
                
            
  19. We now consume the messages from each node. The connections must be on different nodes since if they shared nodes then the consumers would receive the messages sent from different connections.
  20.            
             for (int i = 0; i < numMessages; i ++)
             {
                TextMessage messageA = (TextMessage)consumerA.receive(5000);
    
                System.out.println("Got message: " + messageA.getText() + " from node A");
                
                TextMessage messageB = (TextMessage)consumerB.receive(5000);
    
                System.out.println("Got message: " + messageB.getText() + " from node B");
                
                TextMessage messageC = (TextMessage)consumerC.receive(5000);
    
                System.out.println("Got message: " + messageC.getText() + " from node C");
             }
               
            
  21. And finally (no pun intended), always remember to close your JMS resources after use, in a finally block. Closing a JMS connection will automatically close all of its sessions, consumers, producer and browser objects
  22.            
    	finally
    	{
    	   if (connection0 != null)
    	   {
    	      connection0.close();
    	   }
    	      
    	   if (connection1 != null)
    	   {
    	      connection1.close();
    	   }
    	}