Uniform Distributed Destinations (UDD) feature in WebLogic

The below post depicts a sample configuration of a Uniform Distributed Destination (Queue/ Topic) for the WebLogic JMS feature.

A Distributed Destination represents a group of physical queues, or topics, whose members are hosted by JMS servers in a WebLogic cluster. The distributed destination is bound to a logical JNDI name in the cluster-wide JNDI tree. Applications that use a distributed destination are more highly available than applications that use standalone destinations because it provides.

1.Load balancing

2.Failover for the members of a distributed destination in a cluster.

Pre-requisites:

  1. A cluster configured with at least 2 managed servers.
  2. A persistent store configured for each of the managed server in the cluster.

Steps:

1. Create two JMS Servers and target each one to the migratable servers in the cluster.

a. Login into the Admin Console  –> Navigate to Messaging  –> JMS Servers in the left panel, click new.

b. Create the JMS Server and associate it with the Migratable managed servers of the cluster.

Target each JMS Server to an individual Migratable Managed server.

Note: You need to specify the Persistent store for the JMS Server if it is targeted to a Migratable Server.

You can use the below WLST script to create a FileStore.

from java.util import *

from javax.management import *

import javax.management.Attribute

print 'starting the script ....'

username = 'weblogic'

password = 'weblogic'

AdminURL= 't3://localhost:8001'

connect(username,password,AdminURL)

edit()

startEdit()

cd('/')

cmo.createFileStore('FileStore-0')

cd('/FileStores/FileStore-0')

cmo.setDirectory('G:\BEA103\user_projects\domains\Wonders_Domain')

set('Targets',jarray.array([ObjectName('com.bea:Name=MS1 (migratable),Type=MigratableTarget')], ObjectName))

activate()

 

Alternatively you can configure the FileStores from the Admin Console as well.

Refer the below link for further info.

http://download.oracle.com/docs/cd/E12840_01/wls/docs103/config_wls/store.html#wp1142183

c. Similarly create another JMS  Server and target it to the other managed server in the cluster.

2. Create a JMS Module.

a. Create a JMS Module and target it to the cluster.

3. Create a Sub Deployment.

a. Click on the newly created JMS Module and you will see the ‘SubDeployment’ tab.

b. Click on ‘new’ to create a new Sub Deployment.

c. Target the sub deployment to the two  JMS Servers.

4. Create JMS Resources. (Connection Factory and JMS Destinations).

a. Create a JMS Connection Factory.

b.  Target the Connection Factory to set of JMS Servers created.

5. Create the Distributed Destination (Either Queue or Topic).

a. From the JMS Module page, create a Distributed Queue.

NOTE:  Make sure you enable the “Allocate Members Uniformly” tag to setup Uniform Distributed Queue.

For more details refer the below link.

http://download.oracle.com/docs/cd/E11035_01/wls100/jms_admin/advance_config.html#wp1067272

b. Specify the Sub Deployment and target it to the set of JMS Servers created.

This completes the Uniform Distributed Destination (UDD) configuration.

6. Test the setup.

a.  Compile and execute the below QueueSend.java program.

*******************************************************

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Hashtable;
import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class QueueSend
{
public final static String JNDI_FACTORY="weblogic.jndi.WLInitialContextFactory";
public final static String JMS_FACTORY="CF1";
public final static String QUEUE="DistributedQueue";
private QueueConnectionFactory qconFactory;
private QueueConnection qcon;
private QueueSession qsession;
private QueueSender qsender;
private Queue queue;
private TextMessage msg;
public void init(Context ctx, String queueName)
throws NamingException, JMSException
{
qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
qcon = qconFactory.createQueueConnection();
qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
queue = (Queue) ctx.lookup(queueName);
qsender = qsession.createSender(queue);
msg = qsession.createTextMessage();
qcon.start();
}
public void send(String message) throws JMSException {
msg.setText(message);
qsender.send(msg);
}
public void close() throws JMSException {
qsender.close();
qsession.close();
qcon.close();
}
public static void main(String[] args) throws Exception {
if (args.length != 1) {
System.out.println("Usage: java examples.jms.queue.QueueSend WebLogicURL");
return;
}
InitialContext ic = getInitialContext(args[0]);
QueueSend qs = new QueueSend();
qs.init(ic, QUEUE);
readAndSend(qs);
qs.close();
}
private static void readAndSend(QueueSend qs)
throws IOException, JMSException
{
BufferedReader msgStream = new BufferedReader(new InputStreamReader(System.in));
String line=null;
boolean quitNow = false;
do {
System.out.print("Enter message ("quit" to quit): n");
line = msgStream.readLine();
if (line != null && line.trim().length() != 0) {
qs.send(line);
System.out.println("JMS Message Sent: "+line+"n");
quitNow = line.equalsIgnoreCase("quit");
}
} while (! quitNow);
}
private static InitialContext getInitialContext(String url)
throws NamingException
{
Hashtable<String,String> env = new Hashtable<String,String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, url);
return new InitialContext(env);
}
}

*******************************************************

NOTE: We are sending messages to the url of first managed server in the cluster

b. Compile and execute the below QueueReceive.java program.

*******************************************************

import java.util.Hashtable;
import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class QueueReceive implements MessageListener
{
public final static String JNDI_FACTORY="weblogic.jndi.WLInitialContextFactory";
public final static String JMS_FACTORY="CF1";
public final static String QUEUE="DistributedQueue";
private QueueConnectionFactory qconFactory;
private QueueConnection qcon;
private QueueSession qsession;
private QueueReceiver qreceiver;
private Queue queue;
private boolean quit = false;

public void onMessage(Message msg)
{
try {
String msgText;
if (msg instanceof TextMessage) {
msgText = ((TextMessage)msg).getText();
} else {
msgText = msg.toString();
}
System.out.println("Message Received: "+ msgText );

if (msgText.equalsIgnoreCase("quit")) {
synchronized(this) {
quit = true;
this.notifyAll(); // Notify main thread to quit
}
}
}
catch (JMSException jmse) {
System.err.println("An exception occurred: "+jmse.getMessage());
}
}

public void init(Context ctx, String queueName) throws NamingException, JMSException
{
qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
qcon = qconFactory.createQueueConnection();
qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
queue = (Queue) ctx.lookup(queueName);
qreceiver = qsession.createReceiver(queue);
qreceiver.setMessageListener(this);
qcon.start();
}

public void close()throws JMSException
{
qreceiver.close();
qsession.close();
qcon.close();
}

public static void main(String[] args) throws Exception {
if (args.length != 1) {
System.out.println("Usage: java examples.jms.queue.QueueReceive WebLogicURL");
return;
}
InitialContext ic = getInitialContext(args[0]);
QueueReceive qr = new QueueReceive();
qr.init(ic, QUEUE);
System.out.println("JMS Ready To Receive Messages (To quit, send a "quit" message).");
synchronized(qr) {
while (! qr.quit) {
try {
qr.wait();
}
catch (InterruptedException ie) {}
}
}
qr.close();
}

private static InitialContext getInitialContext(String url) throws NamingException
{
Hashtable<String,String> env = new Hashtable<String,String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, url);
return new InitialContext(env);
}
}

 

*******************************************************

NOTE: We are listening to the JMS messages from the URL of the second managed server in the cluster.

We  are able to read the JMS message successfully on  a different server in the cluster. 🙂

Reference:

http://download.oracle.com/docs/cd/E11035_01/wls100/jms_admin/advance_config.html#wp1079177

Regards,

Wonders Team. 🙂

11 comments

  1. Hi,
    Thanks for publishing useful topics

    I did set up UDD (Queue) following the steps mentioned in the article and using QueueSend (pointing to lnvw-server1:7003) I have sent couple of messages and used QueueReceive (lnvw-server-2:7003) to watch the received messages. But I did not see any messages being received by other Managed Server.

    I can send screen shots & configuration files (if you kindly provide one)

    Managed servers:
    lnvw-server1:7003; lnvw-server2:7003

    Thanks in advance
    Subbu

    1. Hi Subbu,

      Can you try to receive the messages using MDB instead of QueueReceive?

      Best Regards,
      Divya Dureja

  2. Hi Divya,
    Thanks for participating.

    what difference will it make, I mean using MDB?
    If I use the multiple URLs like this in my client like”t3://lnvw-server1:7003,t3://lnvw-server2:7003″ I can see the load is distributed to both the Managed Servers

    But I do not want to use multiple URLs in my client, rather just use one provider url.

  3. Hi Divya,
    Thanks for responding

    What difference will it make if I use MDB?
    All I am missing here is the load balancing.
    Just to let you know that these two managed servers are running in separate boxes.
    Is there any setting/s which are missing? (I did uncheck ‘Server Affinity’ option for Connection Factory)

    1. Hi Subbu,

      The server affinity should be dissabled.

      Please let me know where have you targeted the UDD? Is is targeted on the single server that is t3://lnvw-server1:7003?
      I asked you to try the MDBs because sometimes stand alone clients do not work as expected in UDDs.

      If you can give me your configuration details about the JMS Server and the UDD targets, it will be helpful in analysis.

      Best Regards,
      Divya

  4. Hi Divya,

    After updating my weblogic server to latest version 10.3.4 from 10.0 MP1; I could successfully implement UDD feature (sorry for not mentioning about weblogic server version).

    Best Regards,
    Subbu

  5. Hi,

    IS server Affinity enabled in default connection factory?

    If enabled how to disable it.

    Thanks,
    Ananth

    1. Hi Ananth,

      Server affinity should be disabled. For that, login to the console, JMS Connection Factory -> Configuration -> General

      Uncheck the server affinity enabled box

      Best Regards,
      Divya

  6. Hello, This seems to be a old Post, Not sure if this Post is still active, But I am having similar Issue,
    I have UDQ on Weblogic 10.3.6, It is accepting msgs from a external application( So the connection is being cached I believe)
    The msgs are not being loadbalanced among the 6 member instances of the Queue. By setting the Server Affinity Enabled to false, the messages are being loadbalanced but it is not giving any performance improvement. I see that by setting server affinity Enabled to false. it is making the client to do connection everytime so that is a performance hit. Is there a way to achieve load balancing among all the member instances without having the server affinity Enabled flag to false.
    Any suggestion or response would be helpful.

Comments are closed.