-
1. Re: JMS Topic with high availability for the client?
wdfink Nov 3, 2010 10:22 AM (in response to balmark1)What version of JBoss do you use?
You can configure the message destination as 'clustered', are you sure this is configured?
-
2. Re: JMS Topic with high availability for the client?
balmark1 Nov 3, 2010 11:49 AM (in response to wdfink)Hey Wolf,
Thanks for the reply
Currently using Jboss 4.2.3 here
The Message Queue I'm using however is the latest that comes with the Sun JDK.
If I want to get what I want here, do I have to move from the standard JMS framework? I was assuming that the solution would have to lie with the app server. Configuring a message destination as 'clustered' .. where are you saying this should be done?
I'm flexible here if there's a solution, ie. I can create a HA app for the sole purpose of taking messages off a topic and placing them on a queue for app servers that are sitting in parallel, this HA app doesnt need to be JBoss 4.2.3..
-
3. Re: JMS Topic with high availability for the client?
b.eckenfels Nov 3, 2010 12:10 PM (in response to balmark1)1 of 1 people found this helpfulI think it should work with durable subsriptions where you specify a clirntid and subscrption name. But I am not sure if HornetMQ or JBossMQ allow multiple subsribed consumers with the same ID or if it will disconnect one of it.
http://community.jboss.org/wiki/WhatIsTheCorrectWayToMakeADurableSubscription
-
4. Re: JMS Topic with high availability for the client?
wdfink Nov 3, 2010 4:09 PM (in response to balmark1)Oh,
JBoss 4.2 use JBossMQ by default.
In this case you have not really a clustered JMS, it is only a HA-singleton, this mean that only one JBoss starts the MQ part, if this node will fail one of the other nodes will start the MQ part.
AFAIK there is no configuration for clustered destinations.
Also I'm not really sure how the behaviour is if the MQ fail, it might be that you have to catch the Exception and re-connect via JNDI lookup.
-
5. Re: JMS Topic with high availability for the client?
wdfink Nov 3, 2010 4:11 PM (in response to b.eckenfels)Hi Bernd,
a durable topicis not for this.
This mean that you connect to such topic an, no matter whether you disconnect, the JMS server store each message of the topic for you as long as you ack it.
-
6. Re: JMS Topic with high availability for the client?
balmark1 Nov 4, 2010 11:28 AM (in response to wdfink)Ah, jboss 4.2 might use JBossMQ by default, but I had it setup for suns messaging queue which is now glassfish messaging queue I think and can be setup as a proper jms cluster (I think at the time, the jboss message queue wasn't really upto what were looking for, but it might be now )
Lads over in the Sun site suggested http://community.jboss.org/message/438958?tstart=1 for jboss, but also mentioned glassfish app server and MQ allow shared 'subscriptions'
Thanks for all the info, I hope it'll be as helpful to someone who lands here via google with the same dilema
/Bal
-
7. Re: JMS Topic with high availability for the client?
b.eckenfels Nov 4, 2010 1:14 PM (in response to wdfink)Hallo Wolf-Dieter,
I know what a Topic is, and I know that when you use same client id and subscription name that you can have multiple subscribers and exactly one of them gets the message. This is what Bal asked about.
Gruss
Bernd
-
8. Re: JMS Topic with high availability for the client?
balmark1 Nov 5, 2010 9:03 AM (in response to b.eckenfels)Hey Bernd,
I checked it out, if I wanted to stay clear of clustered web apps and do something really simple, I could do it using durable topics alright!
ie. have 2-3-4-5 servers whatever.. all sitting out on their own.. just waiting for the opportunity to take over
only 1 can subscribe to the topic with the same client id (without doing clustering on the web apps)
so 'hot standby' would be very much 'egar hot standby' .. it'd be possible (I'm assuming not recommended at all tho) ..
that each of the standby servers continously try to connect using the same clientid.. so if the current one drops, the missed messages will be waiting for the next server to manage the connection
I'll be looking at clustered webapps though the idea of the above seems a little 'wrong' .. but it'd work I think..
-
9. Re: JMS Topic with high availability for the client?
balmark1 Nov 5, 2010 9:40 AM (in response to balmark1)1 of 1 people found this helpfulOK another bit ..
Which is alot nicer all together!
If I setup the topic service as
<server>
<mbean code="org.jboss.jms.server.destination.TopicService"
name="jboss.messaging.destination:service=Topic,name=MyTopic"
xmbean-dd="xmdesc/Topic-xmbean.xml">
<depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
<depends>jboss.messaging:service=PostOffice</depends>
<attribute name="SecurityConfig">
<security>
<role name="guest" read="true" write="true" create="true"/>
<role name="publisher" read="true" write="true" create="false"/>
<role name="durpublisher" read="true" write="true" create="true"/>
<role name="test" read="true" write="true" create="true"/>
</security>
</attribute>
<attribute name="Clustered">true</attribute>
</mbean>
</server>
I can attach with multiple clientids .. and the message gets distributed over all my standby servers.. one goes down, and the others just take the load.. lovely
Without clustered = true in the topic, if I tried to connect multiple subscribers with the same clientid.. I'd get
javax.jms.IllegalStateException: Cannot create a subscriber on the durable subscription since it already has subscriber(s)
with clustered = true with the jbossmq, (havent tried with other mq's), I can subscribe lots of times with the same clientid and it works as I'd like it to .. lovely jubley
eg. with the above myjms-service.xml file in the deploy folder, I can run 2 apps to test it..
eg of a test publisher -
package com.c.jms.testing;
import java.util.Hashtable;
import java.util.Properties;
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.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicPublisher;
import javax.jms.TopicSession;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class CreateDurableTopic {
/**
* @param args
*/
public static void main(String[] args) {
String topicName = "/topic/MyTopic";
Context jndiContext = null;
TopicConnectionFactory topicConnectionFactory = null;
TopicConnection topicConnection = null;
TopicSession topicSession = null;
Topic topic = null;
TopicPublisher topicSender = null;
TextMessage message = null;
final int NUM_MSGS;
try {
Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
env.put(Context.URL_PKG_PREFIXES, "org.jboss.naming.client");
env.put(Context.PROVIDER_URL, "jnp://localhost");
jndiContext = new InitialContext(env);
} catch (NamingException e) {
System.out.println("Could not create JNDI API " +
"context: " + e.toString());
System.exit(1);
}
try {
topicConnectionFactory = (TopicConnectionFactory)
jndiContext.lookup("ConnectionFactory");
topic = (Topic) jndiContext.lookup(topicName);
} catch (NamingException e) {
System.out.println("JNDI API lookup failed: " +
e.toString());
System.exit(1);
}
try {
topicConnection =
topicConnectionFactory.createTopicConnection("guest", "guest");
topicSession =
topicConnection.createTopicSession(false,
Session.AUTO_ACKNOWLEDGE);
topicSender = topicSession.createPublisher(topic);
message = topicSession.createTextMessage();
for (int i = 0; i < 50; i++) {
message.setText("This is message " + (i + 1));
System.out.println("Sending message: " +
message.getText());
topicSender.send(message);
try{
Thread.sleep(1000);
}catch(Exception e){};
}
topicSender.send(topicSession.createMessage());
} catch (JMSException e) {
System.out.println("Exception occurred: " +
e.toString());
} finally {
if (topicConnection != null) {
try {
topicConnection.close();
} catch (JMSException e) {}
}
}
}
}
and eg of a test listeners (run multiple times, have a few running.. run the publisher.. stop a few of the listeners and you'll see the others taking over etc.)
package com.c.jms.testing;
import java.util.Hashtable;
import java.util.Properties;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicSubscriber;
import javax.jms.TopicSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class TopicListenerApplication implements MessageListener {
public TopicListenerApplication(){
}
/**
* @param args
*/
public static void main(String[] args) {
String topicName = null;
Context jndiContext = null;
TopicConnectionFactory topicConnectionFactory = null;
TopicConnection topicConnection = null;
TopicSession topicSession = null;
Topic topic = null;
TopicSubscriber topicReceiver = null;
TextMessage message = null;
topicName = "/topic/MyTopic";
System.out.println("Topic name is " + topicName);
TopicListenerApplication listener = new TopicListenerApplication();
/*
* Create a JNDI API InitialContext object if none exists
* yet.
*/
try {
Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
env.put(Context.URL_PKG_PREFIXES, "org.jboss.naming.client");
env.put(Context.PROVIDER_URL, "jnp://localhost");
jndiContext = new InitialContext(env);
} catch (NamingException e) {
System.out.println("Could not create JNDI API " +
"context: " + e.toString());
System.exit(1);
}
try {
topicConnectionFactory = (TopicConnectionFactory)
jndiContext.lookup("ConnectionFactory");
topic = (Topic) jndiContext.lookup(topicName);
} catch (NamingException e) {
System.out.println("JNDI API lookup failed: " + e.toString());
System.exit(1);
}
try {
topicConnection = topicConnectionFactory.createTopicConnection("guest", "guest");
topicConnection.setClientID("testclient");
topicConnection.start();
topicSession = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
topicReceiver = topicSession.createDurableSubscriber(topic, "guest", null, false);//Subscriber(topic);
topicReceiver.setMessageListener(listener);
while(true){
Thread.sleep(1000);
}
} catch (JMSException e) {
System.out.println("Exception occurred: " +
e.toString());
} catch(Exception e){
}
finally {
if (topicConnection != null) {
try {
topicConnection.close();
} catch (JMSException e) {}
}
}
}
public void onMessage(Message message){
System.out.println("Msg received "+message);
if(message instanceof TextMessage){
try{
System.out.println(((TextMessage)message).getText());
}catch(Exception e){
e.printStackTrace();
}
}
}
}
-
10. Re: JMS Topic with high availability for the client?
kmajeed Dec 24, 2010 10:15 AM (in response to balmark1)Hey, I am also trying to setup a HA-Singleton topic, but
my first instance starts successfully but when second node starts i am getting this exception, one thing weird i have noticed is that sometimes second node starts smoothly, i dont get this exception - i had to retry 4-5 times to start the server. Can anyone help me in this?
Stacktrace:
javax.jms.InvalidDestinationException: No such destination: JBossTopic[MyMessage] has it been deployed?
at org.jboss.jms.server.endpoint.ServerSessionEndpoint.createConsumerDelegateInternal(ServerSessionEndpoint.java:1838)
at org.jboss.jms.server.endpoint.ServerSessionEndpoint.createConsumerDelegate(ServerSessionEndpoint.java:252)
at org.jboss.jms.server.endpoint.advised.SessionAdvised.org$jboss$jms$server$endpoint$advised$SessionAdvised$createConsumerDelegate$aop(SessionAdvised.java:94)
atCan you please help me in this?
Khurram