I guess I should be more specific. I am using JBoss within eclipse and my application makes use of message driven beans.
When I run my application, the message producers sends out two messages on the queue. Now I want only ONE thread to pick
up both messages. So essentially I want to set the maximum number of threads to 1.
Here is a sample output from my application:
16:00:24,806 INFO [stdout] (Thread-1 (HornetQ-client-global-threads-25613077)) Queue: I received a TextMessage
Now this shows two threads 1 and 0 as active. I want only thread 0 to pick up these messages. Is there any way to do that?
You should configure the MDB with the appropriate MaxSession activation configuration property. In this case, it would be "1". For example:
@ActivationConfigProperty(propertyName = "maxSession", propertyValue = "1")
That will ensure there is only 1 JMS session used to consume messages.
I did just that. But I still see two different threads consuming messages. And when I set the propertyValue to 2, I
see more than 3 threads active. This confused me!
This is one of the outputs with the propertyValue set to 2:
16:32:10,295 INFO [stdout] (Thread-2 (HornetQ-client-global-threads-10882329)) Queue: I received a TextMessage
16:32:10,299 INFO [stdout] (Thread-4 (HornetQ-client-global-threads-10882329)) Queue: I received a TextMessage
16:32:10,314 INFO [stdout] (Thread-4 (HornetQ-client-global-threads-10882329)) Queue: I received a TextMessage
16:32:10,314 INFO [stdout] (Thread-5 (HornetQ-client-global-threads-10882329)) Queue: I received a TextMessage
Well, these threads come from a pool (i.e. the "global" pool as you can see by the name) which means you aren't guaranteed to get the same thread everytime. However, this really shouldn't matter unless you're doing something crazy like using a ThreadLocal (which, of course, is discouraged).
Thanks for taking out time to reply Justin.
Well, what I really wanted to do was to take performance measurements for my code. So I tried to look for a parameter that could control the number of threads. Is the maxSessions parameter the only way to do that? And if I set it to one, does that mean that my messages are processed one after the other and other messages are blocked till the first one is processed?
Also, which parameter can be used to control the number of threads for each session?
The maxSession activation configuration property controls how many JMS sessions are available for consuming messages from the destination to which the MDB is listening. As I indicated, it isn't really tied to a thread per se.
If you set maxSession to 1 then that does mean that your messages will be processed serially (i.e. not concurrently) so that all other messages are blocked until the current one is consumed.
Oh! I believed there was a pool of threads for each session that could be controlled. There is another parameter: mdb-strict-max-pool and I thought that
was the thread pool for each session.
Ok so increasing the number of sessions adds to concurrency of message processing. Unfortunately, my code takes the
same amount of time for processing messages irrespective of the number of sessions. So I was wondering whether there
was any concurrency in the first place.
1 of 1 people found this helpful
To be clear, mdb-strict-max-pool is for the MDB instances which are fed by the JMS sessions. When a JMS session (managed by the HornetQ JCA RA) receives a message it essentially passes that message to an instance of the MDB (managed by the AS7 EJB container) so onMessage() can actually be invoked. Both the sessions and the instances are pooled independently of each other.
By default, messages will be consumed concurrently. The MDB instance pool defaults to 20 and the JMS session pool size defaults to 15 which means 15 messages can be processed concurrently since the smallest pool determines the overall concurrency (akin to the weakest link in a chain).
The speed at which the onMessage() completes (i.e. the latency) isn't aided by concurrency, but the overall number of messages consumed (i.e. the throughput) usually gets a nice boost.
So just to make things clearer: If I have one thread in my MDB instance pool, increasing the JMS sessions would make no difference to my throughput?
And what so stateless session beans do?
To clarify, the MDB instance pool does not contain threads. It contains instances of the MDB. Likewise, the JMS session pool doesn't contain threads. It contains JMS sessions. The actual threads which do this work come from the HornetQ global pool. You can read more about that in the documented I linked earlier.
That said, your inclination is correct. If you set the MDB instance pool to 1 then it wouldn't matter if you increased the size of the JMS session pool. The opposite is true as well (as I stated in my previous comment). However, please note that having an MDB instance pool which is smaller than the JMS session pool can lead to errors in your log because it would be possible for a JMS session to receive a message but then time out waiting to deliver that message to an MDB instance. This timeout is controlled by the values of instance-acquisition-timeout and instance-acquisition-timeout-unit of the instance pool which the MDB uses. Here is the default configuration:
<strict-max-pool name="mdb-strict-max-pool" max-pool-size="20" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>