9 Replies Latest reply on Jul 24, 2006 5:02 PM by Todd Tidwell

    Best practices question

    Todd Tidwell Newbie

      I have the following requirements:

      A small number of producers that generate around 500 messages a second combined. Each message produced will have an int property of 0 -499. (i.e. 500 different property values). Along with this I also have a large number of consumers, basically one for each unique property value.

      I see two scenarios:

      1) Several destinations, each one accepting messages for a subset of the possible property values (i.e. destination-1 would hold all messages with values 0-9< destination 2 would have 10-19, etc) and have the consumers listen to the appropriate destination and use a message selector.

      2) Create 500 destinations with each consumer listening to the correct destination.

      My question is this: Which one would be the best way to go and why? Or is there a better way I'm not thinking of?



        • 1. Re: Best practices question
          Elias Ross Master


          I didn't know, I would try both and see what was better :-)

          Having a 5-10 selectors is probably fine, 100,000 on a single queue probably isn't a good idea, but I'm not sure where the boundary is.

          500 consumers isn't a big deal, but 100,000 would be.

          • 2. Re: Best practices question
            Todd Tidwell Newbie

            Well, right now I can't get the selectors to work at all. It seems the first consumer with a selector to connect to the destination gets messages, but then none of the other consumers do.

            While we're talking about best practices, which is the better approach? One connection per destination consumer or pool the same connection between multiple consumers?

            • 3. Re: Best practices question
              Tim Fox Master

              Hello Todd-

              There are a couple of things to bear in mind here.

              Firstly, having a large number of selectors on a queue which select few of the messages is generally an anti-pattern and will always have poor performance since, since for every receive() the queue needs to be iterated through until a selected message is obtained for each consumer.

              The performance of this could be improved by using indexes but it will never be great and should be avoided.

              See http://jira.jboss.com/jira/browse/JBAS-1348 for a discussion of this in JBoss MQ - the same theory more or less applies in JBoss Messaging.

              Secondly there is a known bug in JBoss Messaging http://jira.jboss.com/jira/browse/JBMESSAGING-275 which means only the first consumer will get the message, as you have found out.

              This bug is due to be fixed in 1.0.2.

              In the mean-time if you can use a topic instead of a queue this won't exhibit the problems you have been seeing and the performance will always be much better. This is because a topic subscription will not accept any messages that don't match the selector, but a queue will since it cannot know in advance any selectors that consumers might use.

              Finally, the "correct" solution to this problem would be to use a new feature which allows consumers to group themselves according to JMSXGroupId.

              JBoss Messaging will then ensure that any messages with a particular value of JMSXGroupId is only consumed by consumers in that group. Users can configure how many consumers in each group.

              This task is discussed here: http://jira.jboss.com/jira/browse/JBMESSAGING-375

              This allows partitioning of load and this feature is currently scheduled for 1.0.6 (hmmm I'll see if we can get this done sooner)

              • 4. Re: Best practices question
                Todd Tidwell Newbie

                Tim,

                Thank you so much for the response. I can certainly switch to Topics for now and move to the JMSXGroupId later.

                The final question I have is about the best practices with connections. As I asked in one of my previous posts to this thread: Is it better to have one connection per consumer or pool connections between consumers in the same process?

                • 5. Re: Best practices question
                  Tim Fox Master

                  You should try and minimise the amount of connections you create (see JMS1.1 4.3):

                  "Due to the authentication and communication setup done when a Connection is
                  created, a Connection is a relatively heavyweight JMS object. Most clients will
                  do all their messaging with a single Connection. Other more advanced
                  applications may use several Connections. JMS does not architect a reason for
                  using multiple connections (other than when a client acts as a gateway
                  between two different providers); however, there may be operational reasons
                  for doing so."

                  However if you are using a JMS JCA resource adaptor to use JMS, then you should *not* attempt to pool connections yourself. This is because with JCA the "connections" are typically proxies around smart connection references which handle pooling transparently for you.

                  • 6. Re: Best practices question
                    Todd Tidwell Newbie

                    Ok, that all makes a fair amount of sense to me.

                    As for the connections, I'm using the default connection factory that comes with JBoss Messaging and getting it via JNDI and casting it to a TopicConnection. Is that the JCA connector or do I need to go about something else?

                    • 7. Re: Best practices question
                      Ovidiu Feodorov Master

                       

                      toddjtidwell wrote:
                      Well, right now I can't get the selectors to work at all. It seems the first consumer with a selector to connect to the destination gets messages, but then none of the other consumers do.


                      Tim wrote:
                      Secondly there is a known bug in JBoss Messaging http://jira.jboss.com/jira/browse/JBMESSAGING-275 which means only the first consumer will get the message, as you have found out.
                      This bug is due to be fixed in 1.0.2.


                      I've added a test case (org.jboss.test.messaging.jms.selector.SelectorTest.testManyConsumersWithDifferentSelectors()) that simulates the situation you describe and that currently fails. Fixing http://jira.jboss.com/jira/browse/JBMESSAGING-275 should clear it.

                      • 8. Re: Best practices question
                        Ovidiu Feodorov Master

                         

                        toddjtidwell wrote:
                        As for the connections, I'm using the default connection factory that comes with JBoss Messaging and getting it via JNDI and casting it to a TopicConnection. Is that the JCA connector or do I need to go about something else?


                        java:/JmsXA

                        • 9. Re: Best practices question
                          Todd Tidwell Newbie

                          Ok, that's what I'm doing, so we're good to go. I appreciate all the help from everyone who replied.