Tuesday, May 17, 2011

Basic JMS Clustering with Weblogic 11g - Uniform distributed destination

JMS is an integral part of many SOA/Integration projects.
Like any other resource, we want scalability and reliability for our JMS artifacts.

So here is a simple example based on the following simple WLS cluster I've set up





Example 1: Using a UDD(Uniform distributed destination)

Thanks to my colleague Santosh for his support here.

UDDs make sense for both reliability and scalability. Essentially the UDD Queue
will be deployed to my cluster and thus available on both of my managed servers.

Step 1 -Create a JMS Server (JMSServer1)
-- FileStore= JMSFileStore1
-- Target= MgdServer1(Migratable)





Step 2 - Create a JMS System Module for the ConnectionFactory & UDD Queue (JMSModuleCluster)







Step 4 - Test with a JMS Client

--------------------------------------------------
package jmsclient;

import java.util.Hashtable;

import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.TextMessage;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class JMSClient {
public static void main(String [] args) throws JMSException,
NamingException {
final Context ic = getInitialContext();
System.out.println("*** CONTEXT =");
final QueueConnectionFactory qcf = (QueueConnectionFactory)ic.lookup("jms/MyCF");
// Lookup should specify the queue name that is mentioned as "mappedName" in MessageDriven Bean.
final Queue destQueue = (Queue)ic.lookup("jms/MyDistQueue");
ic.close();
final QueueConnection connection = qcf.createQueueConnection();
try {
final QueueSession session = connection.createQueueSession(false, 0);
final QueueSender sender = session.createSender(destQueue);
final TextMessage msg = session.createTextMessage("Hello from Lichtenau - fans of FCN");
sender.send(msg);
} catch (Exception ex) {
ex.printStackTrace();
} finally {
connection.close();
}
}

private static Context getInitialContext() throws NamingException {
Hashtable env = new Hashtable();
// Add InitialContext property assignments here.
env.put( Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory" );
// Note that by default WebLogic server is not created with security, so credentials are not needed.
// TODO: Verify the server address and port number
env.put(Context.PROVIDER_URL, "t3://localhost:7003,localhost:7004");
env.put(Context.SECURITY_PRINCIPAL, "weblogic");
env.put(Context.SECURITY_CREDENTIALS, "welcome1");
return new InitialContext( env );
}
}

------------------------------------------------------------

You can stop any of the 2 managed servers and re-test.
The Queue is alway available.

2 comments:

Anonymous said...

Hi, nice example.

Tried this with a JDBC Store.

Distributed queue JNDI jms/DistributedQueue-0.

All fine until test program:
PROVIDER_URL, "t3://h1:7003,h2:7003");

This gives a javax.naming.NameNotFoundException for jms/DistributedQueue-0. Checking the JNDI trees, the name is indeed present only on h1, not h2. I can fix by modifying test program to use URL h1:7003 only.

The jms/ConnectionFactory-0 on the other hand is present on h1 JNDI and h2 JNDI.

I used the default targetting for the queue and cf but the JNDI behaviour seems to be different.

Is this behaviour what you would expect?

Niall Commiskey said...

what do you mean by JDBC Store?