11 Replies Latest reply on Feb 7, 2008 9:28 AM by ydzsidemiik

    Message priority does not seem to work

    ydzsidemiik

      Hi again,

      What is the expected behavior with respect to queue message ordering due to priority? I am finding that when I place a higher priority message into a queue, it doesn't get delivered ahead of lower priority messages like I would expect.

      For example, if I have a producer sending into a queue at 50m/s priority 4, and every five seconds I send one priority 9 message into the queue, I find that an MDB consuming from the queue at 15m/s only processes a priority 9 every few minutes. Once the deluge of low priority messages ends, the queued higher priority messages go through seemingly all at once. I speculated that buffering might be the issue, but SlowConsumers does not seem to help. Are there any other settings that I could tweak?

      I don't have a test case right now. I am throwing this out there right now in case there are any easy answers, although I'll follow up with a test case if necessary once I have time.

      JBAS 4.2.2/JBM 1.4.0.SP3

        • 1. Re: Message priority does not seem to work
          timfox

          Can you try using pure JMS (i.e. no MDBs) and see if the problem still occurs?

          The MDB layer does some buffering so this may be related to the issue.

          • 2. Re: Message priority does not seem to work
            ydzsidemiik

            I have succeeded in creating a stand-alone example of the behavior in my original post. This download is a ready to go EAR with source included. Simply drop it in the deploy directory of a JBM configuration (mine was built from `all`) to run.

            http://www.mediafire.com/?2y3w3gy2xic

            This example has two producers, one sending priority 4s into a queue at a rate of 50 messages per second and the other priority 9s at a rate of one every five seconds. An MDB consumes from the queue at a rate of 15 messages per second. Watch (you may have to look at the logs afterwards) how the high priority messages, represented by the letter 'H', are sent into the queue but not processed in a timely manner. Use jboss.j2ee:ear=test-prio.ear,jar=test-prio-mdb.jar,name=BootstrapImpl,service=EJB3,type=ManagementInterface in your JMX console to start and stop the senders. You can let them run for a minute or so and then stop them to watch the MDB clear the queue; the 'H' messages appear only intermittently in between large numbers of 'L' messages, even after the producers are stopped.

            I will investigate the pure JMS solution as per your suggestion, but my application was planned, designed, implemented, tested, and placed into production using MDBs -- whatever the outcome, it is the MDB stuff I ultimately have to get working.

            I would be enormously appreciative of any further insight you may have.

            • 3. Re: Message priority does not seem to work
              ydzsidemiik

              I am trying to test the pure JMS approach, but I am seeing this error:

              javax.jms.IllegalStateException: This method is not applicable inside the application server. See the J2EE spec, e.g. J2EE1.4 Section 6.6
              at org.jboss.resource.adapter.jms.JmsSession.checkStrict(JmsSession.java:581)
              at org.jboss.resource.adapter.jms.JmsMessageConsumer.setMessageListener(JmsMessageConsumer.java:136)

              Am I supposed to loop on the receive() method of the consumer myself? That's not completely realistic inside my design. Is there any other way to implement an MDB-like pattern without using MDBs?

              • 4. Re: Message priority does not seem to work
                timfox

                 

                "ydzsidemiik" wrote:
                I am trying to test the pure JMS approach, but I am seeing this error:

                javax.jms.IllegalStateException: This method is not applicable inside the application server. See the J2EE spec, e.g. J2EE1.4 Section 6.6
                at org.jboss.resource.adapter.jms.JmsSession.checkStrict(JmsSession.java:581)
                at org.jboss.resource.adapter.jms.JmsMessageConsumer.setMessageListener(JmsMessageConsumer.java:136)

                Am I supposed to loop on the receive() method of the consumer myself? That's not completely realistic inside my design. Is there any other way to implement an MDB-like pattern without using MDBs?


                That error means you're using the JCA adaptor.

                Pure JMS = no EJB, no JCA.

                I.e. just create a simple JMS client which consumes messages from a queue, and check to see if the priority problem still occurs.

                • 5. Re: Message priority does not seem to work
                  ydzsidemiik

                  Just to clarify, you are talking about a stand alone, J2SE client connecting to JBM from outside the container, correct? This is my understanding of 'no EJB', as I assume you are not talking about writing MBeans.

                  I will try and test this, but I am just trying to make sure I understand you correctly before I start coding.

                  • 6. Re: Message priority does not seem to work
                    timfox

                     

                    "ydzsidemiik" wrote:
                    Just to clarify, you are talking about a stand alone, J2SE client connecting to JBM from outside the container, correct? This is my understanding of 'no EJB', as I assume you are not talking about writing MBeans.

                    .


                    It can be inside or outside the container, it doesn't matter.

                    The key point is it's just a simple pure JMS client, that doesn't rely on JCA or EJB.

                    • 7. Re: Message priority does not seem to work
                      ydzsidemiik

                      I have done as you suggested and written a pure JMS test case, which reproduces the same behavior.

                      http://www.mediafire.com/?ec6wfg9cg1b

                      It is a simple J2SE application, with a main() method. It connects to JBoss Messaging from outside the container.

                      During my testing, I was surprised to find that priorities set on JMS message objects (javax.jms.Message.setJMSPriority(int)) seem to be getting ignored. The "high priority" messages come out of the queue with their priority set to 4, which would explain why they are not being treated preferentially.

                      Priorities set on MessageProducers seem to have an effect though; the priority takes and the message reflects its higher priority (via javax.jms.Message.getJMSPriority()) when it comes out of the queue. Even here however, I noted delays of up to 10 seconds in this particular test in handling these high priority messages. It seems reasonable to expect that for a consumer capable of handling 15 messages per second, one high priority message every five seconds could be handled almost instantly, but I am not a messaging middleware expert and may be missing something fundamental. Please correct me if so.

                      If you run the example, run it first as is to see how priorities set on messages are ignored. Then, uncomment the lines marked with "XXX:" in Main.java to see how setting priorities on the MessageProducer level improves things.

                      • 8. Re: Message priority does not seem to work
                        ydzsidemiik

                        To clarify, I used the following dependencies to run the example:

                        jboss-messaging-1.4.0.SP3\jboss-messaging-client.jar
                        jboss-4.2.2.GA\server\\$MESSAGING_FROM_ALL\lib\jboss-remoting.jar (2.2.2.SP4)
                        jboss-4.2.2.GA\client\\jbossall-client.jar
                        jboss-4.2.2.GA\server\\$MESSAGING_FROM_ALL\deploy\jboss-aop-jdk50.deployer\jboss-aop-jdk50.jar
                        jboss-4.2.2.GA\server\\$MESSAGING_FROM_ALL\lib\javassist.jar
                        jboss-4.2.2.GA\server\\$MESSAGING_FROM_ALL\deploy\jboss-aop-jdk50.deployer\trove.jar
                        jboss-4.2.2.GA\server\\$MESSAGING_FROM_ALL\lib\log4j.jar

                        in exactly that order.

                        • 9. Re: Message priority does not seem to work
                          timfox

                           

                          "ydzsidemiik" wrote:

                          During my testing, I was surprised to find that priorities set on JMS message objects (javax.jms.Message.setJMSPriority(int)) seem to be getting ignored. The "high priority" messages come out of the queue with their priority set to 4, which would explain why they are not being treated preferentially.



                          Yes that is how JMS is supposed to work.

                          JMSPriority must be set on the producer - any value set on the message itself is ignored. See JMS spec 1.1, 3.4.10.


                          • 10. Re: Message priority does not seem to work
                            timfox

                            I haven't run your code but I had a quick look at it. A couple of observations

                            1) As already mentioned. JMSPriority set on a message is ignored - you need to set it on the producer (as per JMS spec)

                            2) JBM (and pretty much every other messaging system) buffers messages on the client side.

                            So basically you have the normal JMS queue on the server, and each consumer keeps a local buffer of messages on the client side to itself and consumes from that. This is is done for performance reasons (it is much quicker than fetching a message every time from the server).

                            The server side queue is ordered by priority and also the client side buffer is ordered by priority.

                            In your case, you are sending messages faster than you can consume them, so your client side buffer becomes full. So any higher priority messages sent after that won't make it to the client side until you consume your buffer.

                            Since your consumers are so slow, you probably don't really need to buffer so you can set this to 1 (prefetchSize- see userguide). This should improve what you see.

                            Also bear in mind that message priorities are a "best effort", there is no guarantee in any JMS system that they will be strictly observed (JMS Spec 3.4.10).

                            In fact it's almost impossible to do this when you have buffer in action.

                            Any reliance on strict ordering of messages will make your app non portable as well.

                            Hope that helps.

                            • 11. Re: Message priority does not seem to work
                              ydzsidemiik

                              It occurred to me last night to, as you suggest, try SlowConsumers in conjunction with setting the priority on the MessageProducer. This morning, I find that it gives me exactly the behavior I desire.

                              So, it turns out this whole affair was all due to a failure to RTFM on my part. I could direct at Sun some impolite comments about the value of a javax.jms.Message.setJMSPriority(int) method which is specified to do nothing, but I was so sure that this wasn't my fault that I'll have to eat a lot of headwear to atone, so I better to get started.

                              My requirement was only that higher priority messages be processed reasonably promptly, not necessarily with any hard deadlines or strict ordering guarantees. I'm satisfied now that I have that, and my app isn't all that portable in the first place. ;)

                              Thanks for your helpful comments.