1 2 Previous Next 22 Replies Latest reply on Oct 7, 2010 6:25 PM by andjarnic

    Can a single queue listener handle mutliple messages simultaneously like servlets handle requests?

    andjarnic Newbie

      Hi all,

       

      We are working with HornetQ and it's been a breeze so far. Very impressed with its ease of use. One thing I have not been able to find thus far is whether or not a single server that provides a listener to a queue, is sent more than one message at at time, like in the servlet model where a single servlet instance can handle many requests each on separate threads. In our initial rollout, we're looking at a single listener server, and we'd like to see if it can handle a few hundred messages a minute or so, most of which are very short in size. My hope is that this does happen, and that I don't need to try to run several servers to handle the JMS message load.

       

      If so, is there some place I configure the number of listener threads for a specific queue? For example, in my app I have 3 listeners, one for each separate queue. If they do handle multiple messages via threads, then one of the particular queues is going to have a few more messages than the other two, so I'd rather give it more threads/resources than the other two.

       

      If this is not possible, then how do you handle 100's to 1000's of messages per minute?

       

      My primary concern is that we'll sometimes pass a message with Base64 encoded file data, up to a couple MBs in size. I don't want this one message to block up other smaller messages while it transfers from the JMS server to the listener server. I do know about using priorities and all that, but I'd prefer not to if possible.

       

      Thank you.

        • 1. Re: Can a single queue listener handle mutliple messages simultaneously like servlets handle requests?
          Tim Fox Master

          I'm not sure exactly what you mean by "listener" - perhaps message consumerr?

           

          Sure, messages are buffered (see user manual flow control chapter), not sure if that answers your question though.

           

          Regarding performance take a look at the enterprise messaging system performance comparison on the wiki for some figures. HornetQ can do over 700 thousand small messages per *second* on modest hardware.

          • 2. Re: Can a single queue listener handle mutliple messages simultaneously like servlets handle requests?
            andjarnic Newbie

            Thank you for the reply Tim. I suppose I mean message consumer..yes. I was hoping to be able to handle several messages simultaneously on a single server with a single message consumer listener class. I have a class deployed in a web-app (GlassFish v3.. waiting on JBoss 6 final to switch over). It has a single class that is a queue listener for one queue only. I send about 30 messages to the queue from 3 different clients. Can all 30 get handled at the same time with just the one server/message consumer listener, via multiple threads starting up to handle the messages concurrently? I compare this to the servlet model, where each time a request comes in, it spawns a thread (or pulls one from a pool of threads) to handle the request. It allows servlets to handle far more reuqests simulatneously than if it was only using one thread. So I just wanted to make sure that in order to handle 30 simultaneous messages in the queue on the JMS server, that it can send all 30 messages one after another as fast as it can, to the single message consumer and that consumer would spawn threads to handle multiple messages at once, as opposed to handling them one at a time.

             

            What is considered modest hardware? Maybe I missed the specs on the machine that was handling the messages?

            • 3. Re: Can a single queue listener handle mutliple messages simultaneously like servlets handle requests?
              Andy Taylor Master

              i dont think tht really makes sense, if you want messages consumed asynchronously then just create more message consumers. This is sort of the model MDB's use, i.e. there is usually a pool of MDB's each with its own consumer

              • 4. Re: Can a single queue listener handle mutliple messages simultaneously like servlets handle requests?
                Tim Fox Master

                +1 As Andy says, if you want more parallel delivery create more consumers.

                 

                BTW the specs are in the report

                • 5. Re: Can a single queue listener handle mutliple messages simultaneously like servlets handle requests?
                  andjarnic Newbie

                  Hey all,

                   

                  Sorry for the 2 week delay.. been swamped...

                   

                   

                  I am not sure I understand how this works then. I define a message listener class, that registers with the JMS server to listen for messages. When one becomes available, it sends it to my message listener instance. If there were 5 ready to be handled, the other 4 basically wait until this one message listener instance I have is done processing the first message. Meanwhile, that processing used about .0001% of the computer capability. How is it that I create more message listener instances to handle a lot more at once?

                   

                  So would something like this work:

                   

                   

                  Context ctx = new InitialContext(env);
                  QueueConnectionFactory qFactory = (QueueConnectionFactory) ctx.lookup("/ConnectionFactory");
                  qConnect = qFactory.createQueueConnection();
                  qSession = qConnect.createQueueSession(false,Session.AUTO_ACKNOWLEDGE);

                   

                  for(int cntr = 0; cntr < 100; cntr++){

                    qReceiver = qSession.createReceiver(getListenerQueue());
                    qReceiver.setMessageListener(new MyServerQueueListener());

                  }

                   

                  qConnect.start();

                   

                   

                  Naturally I'd want to keep references to the MyServerQueueListener instances and such, but is that the general idea? I would have thought the JMS implementation handled the ability to spawn threads and instances of the listener class to handle more messages.

                   

                  Is there some way to create them on the fly.. sort of like the old JDBC connection pooling days..where you put maybe 5 connections in the pool, if more were needed it create them, adding to the pool, then eventually would remove them if after a 30 minute timeout they weren't used?

                   

                  Thanks guys.

                  • 6. Re: Can a single queue listener handle mutliple messages simultaneously like servlets handle requests?
                    Andy Taylor Master

                    It doesnt make sense for a consumer to receive messages in parallel why would you want to do that, it goes against  the whole PUB/SUB model.  I don't really understand what you are trying to achieve, maybe you are using the wrong technology. Like I said before, if you want to consume messages in parallel  just create more consumers. This is really an application level problem.

                    • 7. Re: Can a single queue listener handle mutliple messages simultaneously like servlets handle requests?
                      Leos Bitto Novice

                      andjarnic wrote:

                       

                       

                      So would something like this work:

                       

                       

                      Context ctx = new InitialContext(env);
                      QueueConnectionFactory qFactory = (QueueConnectionFactory) ctx.lookup("/ConnectionFactory");
                      qConnect = qFactory.createQueueConnection();
                      qSession = qConnect.createQueueSession(false,Session.AUTO_ACKNOWLEDGE);

                       

                      for(int cntr = 0; cntr < 100; cntr++){

                        qReceiver = qSession.createReceiver(getListenerQueue());
                        qReceiver.setMessageListener(new MyServerQueueListener());

                      }

                       

                      qConnect.start();

                       

                       

                      Naturally I'd want to keep references to the MyServerQueueListener instances and such, but is that the general idea?

                       

                      You got it wrong - you should use only one MessageListener in each Session. Of course you can create more Sessions and then use a MessageListener in each of them - only then the client library of your JMS provider (HornetQ) could run your MessageListener's methods onMessage concurrently in multiple threads. The JMS specification clearly says that the only method of Session and its objects which can be executed concurrently is close().

                      • 8. Re: Can a single queue listener handle mutliple messages simultaneously like servlets handle requests?
                        Andy Taylor Master
                        You got it wrong - you should use only one MessageListener in each  Session. Of course you can create more Sessions and then use a  MessageListener in each of them - only then the client library of your  JMS provider (HornetQ) could run your MessageListener's methods  onMessage concurrently in multiple threads. The JMS specification  clearly says that the only method of Session and its objects which can  be executed concurrently is close().

                        Thats not true, you can create as many consumers as you want on a single session, in fact, connections and sessions are heavy weight objects so should always be re used where possible.

                        • 9. Re: Can a single queue listener handle mutliple messages simultaneously like servlets handle requests?
                          andjarnic Newbie

                          @Andy, perhaps I am not communicating it correctly.. I am not entirely sure the right way to say it. I have a single server that registers a consumer. From what Tim said, a JMS server with modest hardware could handle 700,000 small messages per second... obviously thats the server/queue processing and dispatching them. Where does it dispatch 700,000 messages to? Did someone set up 700,000 separate servers to each handle 1 message? Obviously not. What I am trying to figure out is how my quad core 32GB server can handle multiple messages at once, using it's capacity of memory and cpu speed to its fullest. Much like a servlet engine can handle 1000's of requests simultaneously, by spawning threads and instances of some framework to handle each request. I would suspect there is some way, be it some way I have to write the code to handle it, or some configuration on the consumer JMS side, to handle more than one message from the JMS queue at the same time. They are each unique/different messages on the JMS queue.

                           

                          @Leos, ok..makes sense.. but clearly Andy/Tim are indicating that what I am saying does not make sense. They've both said just create more consumers. Is this the "right path" to creating more consumers on a single server? Ideally I'd have a List of Session objects, loop through them, createing receivers and setting a new instance of MyServerQueueListener on each? If that is the right way to do it, what about threading? Is that what you mean by each session can then be run in it's own thread? I am basically trying to figure out how to do some sort of consumer pool, so that my single server can handle multiple messages at once to maximize the capacity of the computer.

                           

                          Thanks all. Sorry if this is confusing or not clear. Setting up HornetQ and working with JMS was so easy initially, I figured there must be some configuration or something I a missing to have my single server that runs the JMS consumer code, to handle tons of messages at once so that the JMS server isn't filling up. Assuming the JMS server can dispatch 100's of thousands of messages per second, but each processing of a message on the consumer may take a couple seconds.. would basically mean the JMS server is going to fill up (assuming I actually had that many messages coming in to it, which thankfully I don't). I want to make sure the throughput of the JMS server and the handling of all those messages is as fast and effecient as possible. With my one server handling all dispatched messages, it would be ideal if it could process 100's of them in parallel rather than one at a time.

                          • 10. Re: Can a single queue listener handle mutliple messages simultaneously like servlets handle requests?
                            Tim Fox Master

                            Andy Taylor wrote:

                             

                            You got it wrong - you should use only one MessageListener in each  Session. Of course you can create more Sessions and then use a  MessageListener in each of them - only then the client library of your  JMS provider (HornetQ) could run your MessageListener's methods  onMessage concurrently in multiple threads. The JMS specification  clearly says that the only method of Session and its objects which can  be executed concurrently is close().

                            Thats not true, you can create as many consumers as you want on a single session, in fact, connections and sessions are heavy weight objects so should always be re used where possible.

                            Andy - Leos is right.

                             

                            Although you can create as many message consumers as you want on a single JMS session, those consumers will NOT receive messages in parallel. All message delivery on a JMS session is serialized as per JMS spec.

                             

                            If you want parallel delivery you must create multiple sessions and have each session have it's own consumer.

                            • 11. Re: Can a single queue listener handle mutliple messages simultaneously like servlets handle requests?
                              Andy Taylor Master
                              @Andy, perhaps I am not communicating it correctly.. I am not entirely  sure the right way to say it. I have a single server that registers a  consumer. From what Tim said, a JMS server with modest hardware could  handle 700,000 small messages per second... obviously thats the  server/queue processing and dispatching them. Where does it dispatch  700,000 messages to? Did someone set up 700,000 separate servers to each  handle 1 message? Obviously not. What I am trying to figure out is how  my quad core 32GB server can handle multiple messages at once, using  it's capacity of memory and cpu speed to its fullest. Much like a  servlet engine can handle 1000's of requests simultaneously, by spawning  threads and instances of some framework to handle each request. I would  suspect there is some way, be it some way I have to write the code to  handle it, or some configuration on the consumer JMS side, to handle  more than one message from the JMS queue at the same time. They are each  unique/different messages on the JMS queue.

                              Its pretty simple, the more consumers you have on a queue the quicker messages will be consumed from the queue! Maybe a simple JMS tutorial would be a good place to start

                              • 12. Re: Can a single queue listener handle mutliple messages simultaneously like servlets handle requests?
                                Tim Fox Master

                                andjarnic wrote:

                                 

                                @Andy, perhaps I am not communicating it correctly.. I am not entirely sure the right way to say it. I have a single server that registers a consumer. From what Tim said, a JMS server with modest hardware could handle 700,000 small messages per second... obviously thats the server/queue processing and dispatching them. Where does it dispatch 700,000 messages to? Did someone set up 700,000 separate servers to each handle 1 message? Obviously not. What I am trying to figure out is how my quad core 32GB server can handle multiple messages at once, using it's capacity of memory and cpu speed to its fullest. Much like a servlet engine can handle 1000's of requests simultaneously, by spawning threads and instances of some framework to handle each request. I would suspect there is some way, be it some way I have to write the code to handle it, or some configuration on the consumer JMS side, to handle more than one message from the JMS queue at the same time. They are each unique/different messages on the JMS queue.

                                 

                                @Leos, ok..makes sense.. but clearly Andy/Tim are indicating that what I am saying does not make sense. They've both said just create more consumers. Is this the "right path" to creating more consumers on a single server? Ideally I'd have a List of Session objects, loop through them, createing receivers and setting a new instance of MyServerQueueListener on each? If that is the right way to do it, what about threading? Is that what you mean by each session can then be run in it's own thread? I am basically trying to figure out how to do some sort of consumer pool, so that my single server can handle multiple messages at once to maximize the capacity of the computer.

                                 

                                Thanks all. Sorry if this is confusing or not clear. Setting up HornetQ and working with JMS was so easy initially, I figured there must be some configuration or something I a missing to have my single server that runs the JMS consumer code, to handle tons of messages at once so that the JMS server isn't filling up. Assuming the JMS server can dispatch 100's of thousands of messages per second, but each processing of a message on the consumer may take a couple seconds.. would basically mean the JMS server is going to fill up (assuming I actually had that many messages coming in to it, which thankfully I don't). I want to make sure the throughput of the JMS server and the handling of all those messages is as fast and effecient as possible. With my one server handling all dispatched messages, it would be ideal if it could process 100's of them in parallel rather than one at a time.

                                I'm not really sure what you are asking here. If you can ask a short, concise, directed question we can attempt to answer it, it's not easy to parse long emails.

                                • 13. Re: Can a single queue listener handle mutliple messages simultaneously like servlets handle requests?
                                  Andy Taylor Master

                                  Andy - Leos is right.

                                   

                                  Although  you can create as many message consumers as you want on a single JMS  session, those consumers will NOT receive messages in parallel. All  message delivery on a JMS session is serialized as per JMS spec.

                                   

                                  If you want parallel delivery you must create multiple sessions and have each session have it's own consumer.

                                  Yeah youre right of course,  i misunderstood his post, i thought the was saying that the JMS spec doesnt allow it

                                  • 14. Re: Can a single queue listener handle mutliple messages simultaneously like servlets handle requests?
                                    Andy Taylor Master
                                    @Leos,  ok..makes sense.. but clearly Andy/Tim are indicating that what I am  saying does not make sense. They've both said just create more  consumers. Is this the "right path" to creating more consumers on a  single server? Ideally I'd have a List of Session objects, loop through  them, createing receivers and setting a new instance of  MyServerQueueListener on each? If that is the right way to do it, what  about threading? Is that what you mean by each session can then be run  in it's own thread? I am basically trying to figure out how to do some  sort of consumer pool, so that my single server can handle multiple  messages at once to maximize the capacity of the computer.

                                    You keep saying 'creating consumers on a server', what do you meanby this, remember a consumer is a client, if you are using a server why dont you just use MDB's and then they will do the pooling for you

                                    1 2 Previous Next