6 Replies Latest reply on Oct 24, 2007 4:19 PM by genman

    maxMessages

      http://wiki.jboss.org/wiki/Wiki.jsp?page=ConfigJMSMessageListener defines "maxMessages" as follows:


      maxMessages - read this number of messages before delivering messages to the mdb (each message is delivered individually on the same thread in an attempt to avoid context excessive context switching) - default 1


      Which seems to behave as one would like it. Set it to two, and two messages are processed at a time. Set it to four, and four get processed at a time. And that number of MDBs get constructed.

      In other words, maxMessages seems to define the number of MDBs that will be instantiated, and each MDB is single threaded. Is this correct?

      In EJB2, there you could configure min-pool-size and max-pool-size, but the MDBs seemed to be multi-threaded. Certainly, setting max-pool-size to 1 did not turn your bean into a singleton. So EJB3 would definitely seem to be a step forward. Having said that, is it possible or relevant to ask about controlling the "threadedness" of EJB3 MDBs? Am I right to assume that I don't need to worry about it?

      Thanks in advance for the clarification!

        • 1. Re: maxMessages

          Perhaps I should also add that the default "maxMessages" value would seem to be 15. I will correct the wiki if somebody can confirm my testing.

          • 2. Re: maxMessages
            genman

            I think you're confusing "maxSession" with "maxMessages". "maxSession" controls the number of concurrently operating threads. The pool size controls the number of MDB object instances created and pooled by JBoss. This pool size should be larger than the number of concurrent threads, otherwise the threads get blocked.

            Anyway, you probably don't need to worry about messing with these settings in EJB3, unless there's some performance issue you're dealing with.

            • 3. Re: maxMessages

              I am probably confused. ;-) I generally am.

              I think sessions worked the way you suggest in previous versions of JBoss / EJB. I read maxSessions to refer to the number of threads that can deliver messages to the queue at a time:


              the maximum number of jms sessions that can concurrently deliver messages to this mdb - default 15


              maxMessages definitely controls the number of MDBs instantiated, and there is a one-to-one correlation between messages being processed, and MDBs instantiated. Ie, setting maxMessages to 4 results in messages being processed 4 at a time.

              What I didn't do last night was set maxMessages to a number greater than maxSessions. So I just set maxMessages to 20: 20 MDBs where instantiated, and 20 messages where processed at a time (in fact, I sent through more than 20 messages - they where still processed 20 at a go).

              I have just run the test a different way. Last night I set the MDBs to simply iterate through a simple for loop until 10 seconds had passed. This evening I ran the test calling a database query that took ten seconds to elapse (so, in theory, perhaps the MDB could yield its thread to be used by another message call). The results where the same: there is a one-to-one correspondence between maxMessages, and message throughput (which I think is a good thing!).

              And, there doesn't seem to be a pool size setting anymore. Its not reflected in ConfigJMSMessageListener, and JBoss throws an error if you try to set it.

              I do need to mess with these settings: our resource constraints lie in the database, not in JBoss. I need to be able to control the throughput to ensure that the database does not get overwhelmed.

              I would very much like to get better clarity on the definition of maxSession and maxMessages, so if anybody can shed any light, I'm listening!

              • 4. Re: maxMessages

                 

                "Renen" wrote:

                I would very much like to get better clarity on the definition of maxSession and maxMessages, so if anybody can shed any light, I'm listening!


                MaxSessions is the number of concurrent threads delivering messages.

                e.g. 15 messages arrive and are delivered concurrently on 15 threads.

                MaxMessages is defined in the spec for ServerSessionPool, it is the number
                of messages that are received before it delivers the messages.

                e.g. 3 messages arrive and are delivered one after the other (in different transactions)
                on the same thread.

                I'd ignore MaxMessages (leave it a 1).
                It is a stupid optimization (slightly reduces context switching)
                that increases latency unless you have continous and high throughput of messages.

                i.e. one message arrives but it will sit there and not be delivered until MaxMessages
                have arrived.

                • 5. Re: maxMessages

                  Hi Adrian, thanks for taking the time to reply. I have been chasing ill defined deadlines and wanted to make sure that I answered coherently rather than just shooting my mouth off.

                  I have re-run my experiments.

                  > I'd ignore MaxMessages (leave it a 1).

                  If you don't set this message, the messages are delivered as they are received. Here is an exert from my logging:

                  11:13:55,843 INFO [STDOUT] I will send 2 message which will each execute for ten seconds.
                  11:13:55,890 INFO [STDOUT] Done generating messages.
                  11:13:55,968 INFO [STDOUT] A MDB has been CONSTRUCTED
                  11:13:55,968 INFO [STDOUT] A MDB has been CONSTRUCTED
                  11:13:56,000 INFO [STDOUT] 2: starting
                  11:13:56,000 INFO [STDOUT] 1: starting
                  11:14:06,000 INFO [STDOUT] 1: ending [75778423]
                  11:14:06,000 INFO [STDOUT] 2: ending [89124368]
                  


                  If you set it to one, the messages are delivered one by one:

                  11:16:25,140 INFO [STDOUT] I will send 2 message which will each execute for ten seconds.
                  11:16:25,187 INFO [STDOUT] Done generating messages.
                  11:16:25,250 INFO [STDOUT] A MDB has been CONSTRUCTED
                  11:16:25,265 INFO [STDOUT] 1: starting
                  11:16:35,265 INFO [STDOUT] 1: ending [119664541]
                  11:16:35,281 INFO [STDOUT] 2: starting
                  11:16:45,281 INFO [STDOUT] 2: ending [123000458]
                  


                  > i.e. one message arrives but it will sit there and not be delivered
                  > until MaxMessages have arrived.

                  So, I set MaxMessages to 3. Clearly the two messages are delivered without any greater delay than in the preceding two scenarios:

                  11:22:41,093 INFO [STDOUT] I will send 2 message which will each execute for ten seconds.
                  11:22:41,140 INFO [STDOUT] Done generating messages.
                  11:22:41,203 INFO [STDOUT] A MDB has been CONSTRUCTED
                  11:22:41,234 INFO [STDOUT] A MDB has been CONSTRUCTED
                  11:22:41,234 INFO [STDOUT] 1: starting
                  11:22:41,234 INFO [STDOUT] 2: starting
                  11:22:51,234 INFO [STDOUT] 1: ending [84453291]
                  11:22:51,234 INFO [STDOUT] 2: ending [83080051]
                  


                  Which is a huge pity: this control would have allowed me to throttle throughput (which is what I am really trying to do). From what you've said, relying on this behaviour is probably imprudent!

                  Should I report a bug? Or is my code wrong (its included below)? Otherwise, how should I throttle throughput?

                  Thank you!

                  Renen.

                  Note: I have either eliminated the entire propertyName = "MaxMessages", propertyValue="3" line, or changed the propertyValue setting depending on the scenario (above).

                  @MessageDriven(
                   mappedName = "jms/TestThroughputConsumer", activationConfig = {
                   @ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/TestThroughput"),
                   @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
                   @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
                  
                   @ActivationConfigProperty(propertyName = "MaxMessages", propertyValue="3")
                   }
                   )
                  public class TestThroughputConsumer implements MessageListener {
                  
                   public void onMessage(Message message) {
                   int id = getIntFromMessage(message);
                   System.out.println(id + ": starting");
                  
                   Date end = new Date( (new Date()).getTime() + 10000 );
                   long i = 0;
                   while ( (new Date()).before(end) ) {
                   i = i+1;
                   }
                   System.out.println(id + ": ending [" + i + "]");
                   }
                  
                   @PostConstruct
                   public void postConstruct() {
                   System.out.println("A MDB has been CONSTRUCTED");
                   }
                  
                   @PreDestroy
                   public void preDestroy() {
                   System.out.println("MDB about to be DESTROYED");
                   }
                  
                   private int getIntFromMessage(Message message) {
                   int retval = 0;
                   try {
                   TestThroughput t = (TestThroughput)((ObjectMessage)message).getObject();
                   retval = t.getID();
                   } catch (JMSException e) {
                   Log.logError(0, "Error extracting message: " + e.getMessage(), this.getClass().getName());
                   }
                   return retval;
                   }
                  
                  
                  }
                  




                  • 6. Re: maxMessages
                    genman


                    What you really want to do is throttle at the consumer level, i.e. JMS connection level or through the inflow adapter. Unfortunately, JBossMQ (and JBM) do not support this as a feature. Easier might be the latter.

                    Take a look at this example:
                    http://wiki.jboss.org/wiki/Wiki.jsp?page=JBossJCAMessageInflowExample

                    Then consider wrapping the existing JCA implementation, adding your own activation properties, and of course add code to actually throttle. Though, I'm not sure where all of this might go.