11 Replies Latest reply on Dec 5, 2005 10:12 PM by Adrian Brock

    best way of acheiving request response format

    rohit sharma Newbie

      hello all ,
      can anyone please tell me whats the best way to achieve request response format between two application.

      i have one it this way, please correct me if i am wrong.

      once i get a request , i create a message and i create a temporary queue for every request and send that temp queue destination along with my request to some appication who is listening , the listeneer then extracts my destination ans responds to that destination (temp queue) which i had created and to which i am listening.

      but what i am worried about it that for every request i am creating a temp queue. so will it work in real time application where lets say 20-30 requests come at once, so my app will ccreate 20-30 temp queue. I am using Jboss 4.0.
      and one more thing. are these temp queue destroyed automatically .if yes then i guess my approach should work i guess. i am pasting my code as well .
      please do help me . thanks


      
      package test.jms;
      
      import java.util.HashMap;
      import java.util.Properties;
      import javax.jms.Destination;
      import javax.jms.JMSException;
      import javax.jms.Queue;
      import javax.jms.QueueConnection;
      import javax.jms.QueueConnectionFactory;
      import javax.jms.QueueReceiver;
      import javax.jms.QueueSender;
      import javax.jms.QueueSession;
      import javax.jms.Session;
      import javax.jms.TemporaryQueue;
      import javax.jms.TextMessage;
      import javax.naming.Context;
      import javax.naming.InitialContext;
      import javax.naming.NamingException;
      
      
      public class PrototypeSenderReceiver {
       String queueName = null;
       Context jndiContext = null;
       QueueConnectionFactory queueConnectionFactory = null;
       QueueConnection queueConnection = null;
       QueueSession queueSession = null;
       Queue queue = null;
       Queue replyQueue=null;
       QueueSender queueSender= null;
       TextMessage requestMessage = null;
       QueueReceiver queueReceiver=null;
       TemporaryQueue tempQueue=null;
      
      
       public static void main(String[] args) {
       }
      
       public String sendMessage(HashMap messageMap) {
       PrototypeSenderReceiver m = new PrototypeSenderReceiver();
       try {
       m.establishConnectionAndSend(messageMap);
       } catch (Exception e) {
       e.printStackTrace();
       }
       return messageMap.get("q").toString();
       }
      
      
       private void establishConnectionAndSend(HashMap messageMap){
       queueName = "queue/testQueue";
       try {
       Properties env = new Properties();
       env.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.NamingContextFactory");
       jndiContext = new InitialContext();
       queueConnectionFactory = (QueueConnectionFactory)jndiContext.lookup("QueueConnectionFactory");
       queue = (Queue) jndiContext.lookup(queueName);
       }catch (NamingException e) {
       System.out.println("JNDI API lookup failed: " + e.toString());
       System.exit(1);
       }
       try {
       queueConnection = queueConnectionFactory.createQueueConnection();
       queueSession = queueConnection.createQueueSession (false, Session.AUTO_ACKNOWLEDGE);
       queueSender = queueSession.createSender(queue);
       requestMessage = queueSession.createTextMessage();
       //TODO create XML MESSAGE out of HASHMAP and set it in requestMessage
       requestMessage.setText("new value");
       tempQueue = queueSession.createTemporaryQueue();
       Destination replyDestination = tempQueue;
       System.out.println("there");
       requestMessage.setJMSReplyTo(replyDestination);
       queueSender.send(requestMessage);
      
       System.out.println("******************************");
       QueueReceiver qr = queueSession.createReceiver(tempQueue);
       queueConnection.start();
      
       TextMessage replyMessage = (TextMessage)qr.receive(30000);
       if(replyMessage ==null){
       System.out.println("3");
       }else{
       System.out.println("done with this " + replyMessage.getText());
       }
      
       } catch (Exception e) {
       System.out.println("stacktrace");
       e.printStackTrace();
       System.out.println("Exception occurred: " + e.toString());
       }
       finally {
       if (queueConnection != null) {
       try {
       queueConnection.close();
       }catch (JMSException e) {
       }
       }
       }
       }
      }
      
      
      
      
      
      


        • 1. Re: best way of acheiving request response format
          crazytony Newbie

          We're just getting over using Temporary Queues for replies.

          We've found that using a Topic with a Selector is much faster and uses MUCH less memory.

          • 2. Re: best way of acheiving request response format
            Elias Ross Master

            rohit_mca2000 -

            My recommendation is since you (eventually) need to test your application under load, you test it and decide if the performance is adequate or not. Your architecture seems correct.

            I guess I would take "crazytony"'s advice with a grain of salt, since I know selectors don't scale that well, having looked at the code myself.

            • 3. Re: best way of acheiving request response format
              rohit sharma Newbie

              hmmm... ok crazytony, and genman for replying. will have to check my application under load, lets see wha happens.

              • 4. Re: best way of acheiving request response format
                rohit sharma Newbie

                one question Mr.genman , What are chancesof a bottleNeck taking place at Jboss serve. Lets say at a moment around 200-300 requests come at once , so that would mean creation of 200-300 temporary queues, as many connectios and sessions. can that lead to a BottleNeck or Memory leackage

                • 5. Re: best way of acheiving request response format
                  crazytony Newbie

                  genman,

                  Can you point to the lines of code which cause selectors with topics to not scale well?

                  Perhaps you are confused and are referring to selectors with queues, which are a really, really bad idea.



                  rohit_mca2000,

                  We got the idea to switch to Topics with Selectors after seeing that every other JMS implementation out there (ActiveMQ, WebSphere MQ, WLMQ) provide better slightly better performance with Topics and Selectors.

                  Google for JMS Topics and Selectors and you'll find quite a few of them.

                  We run about 20,000 messages per server during our peak 8 hours. We saw memory usage drop by 100M (out of 1024M) by switching from TemporaryQueues to Topics with selectors.

                  We've also seen our full GC invocations drop by 40% and the average length of our Full GC go from 15 seconds to 12 seconds.

                  My advice to you is this: it's not impossible to switch mechanisms (we coded it so we can do it with a properties file switch).

                  Follow the recommended practices:
                  Cache the connection
                  Create a Session per thread

                  • 6. Re: best way of acheiving request response format
                    rohit sharma Newbie

                    ok crazytony , will take ur advice and find out a way to cache connections and sessions, however we are going forward with one queue for request and other queue for response with selectors . this is going to be a real-time application where thousands of requests can come at a go, hope this works
                    thanks

                    • 7. Re: best way of acheiving request response format
                      Elias Ross Master


                      crazytony - I wasn't trying to "diss" you with that comment, but my approach is to always write things the logical way, then performance test them, then apply any optimizations.

                      Still, for every message sent to a topic, JBoss has to evaluate the selector against every topic listener. This seems problematic if there were thousands of outstanding requests.

                      But for 20-30 max listeners, I can see that if many are created/destroyed per second, for example, then having a topic would scale better.

                      • 8. Re: best way of acheiving request response format
                        rohit sharma Newbie

                        I some times feel , how couldnt SUN think of this such an importanat issue while creating JMS that they need to give some API for acheiving request response , neways , i am going ahead with queues with message selectors. thank to you both for your valuable comments

                        • 9. Re: best way of acheiving request response format
                          Elias Ross Master


                          javax.jms.QueueRequestor ?

                          • 10. Re: best way of acheiving request response format
                            rohit sharma Newbie

                            but genman, that requestor class in such a shit. i mean it makes a blocking call till it gets a response, and for it too we everytime have to create a temporary queue , and put it into a destination, and feed this detination in to request messages, then and only then that Requestor class works.

                            so finally we come back to ground zero.

                            • 11. Re: best way of acheiving request response format
                              Adrian Brock Master

                              STOP!!!!!!!!!!

                              Queue with selectors == Brain dead anti-pattern (JMS is not database that you can run queries against).

                              Topic with selectors == fine. The selector is just a filter

                              On QueueRequestor, implement your own. This is like no lines of code:

                              /*
                               * JBoss, Home of Professional Open Source
                               * Copyright 2005, JBoss Inc., and individual contributors as indicated
                               * by the @authors tag. See the copyright.txt in the distribution for a
                               * full listing of individual contributors.
                               *
                               * This is free software; you can redistribute it and/or modify it
                               * under the terms of the GNU Lesser General Public License as
                               * published by the Free Software Foundation; either version 2.1 of
                               * the License, or (at your option) any later version.
                               *
                               * This software is distributed in the hope that it will be useful,
                               * but WITHOUT ANY WARRANTY; without even the implied warranty of
                               * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
                               * Lesser General Public License for more details.
                               *
                               * You should have received a copy of the GNU Lesser General Public
                               * License along with this software; if not, write to the Free
                               * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
                               * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
                               */
                              package javax.jms;
                              
                              /**
                               * A queue requestor
                               *
                               * @author Chris Kimpton (chris@kimptoc.net)
                               * @author Adrian Brock (adrian@jboss.com)
                               * @version $Revision: 1.9 $
                               */
                              public class QueueRequestor
                              {
                               private QueueSession queueSession = null;
                              
                               private QueueSender requestSender = null;
                              
                               private QueueReceiver replyReceiver = null;
                              
                               private TemporaryQueue replyQueue = null;
                              
                               public QueueRequestor(QueueSession session, Queue queue) throws JMSException
                               {
                               queueSession = session;
                              
                               requestSender = queueSession.createSender(queue);
                               replyQueue = queueSession.createTemporaryQueue();
                               replyReceiver = queueSession.createReceiver(replyQueue);
                               }
                              
                               public Message request(Message message) throws JMSException
                               {
                               message.setJMSReplyTo(replyQueue);
                               message.setJMSDeliveryMode(DeliveryMode.NON_PERSISTENT);
                               requestSender.send(message);
                               return replyReceiver.receive();
                               }
                              
                               public void close() throws JMSException
                               {
                               try
                               {
                               replyReceiver.close();
                               }
                               catch (JMSException ignored)
                               {
                               }
                               try
                               {
                               replyQueue.delete();
                               }
                               catch (JMSException ignored)
                               {
                               }
                               queueSession.close();
                               }
                              }