1 2 Previous Next 27 Replies Latest reply on Feb 11, 2009 12:29 AM by konami Go to original post
      • 15. Q
        tnine

        Thank you for all your help. I got everything running by importing the jars you listed from my server into my Jboss server lib into my maven repository. I also fixed my client connectivity issue by upgrading to Spring 2.5.3, and using the org.springframework.jms.connection.CachingConnectionFactory to create and pool the same number of JMS connections as partition readers. Doing this greatly increases my performance. Running my client and JBoss on my dual processor machine, I can now queue around 1000 messages a minute, give or take a few depending on the size. I deployed this to our blade clusters and I had nearly an exponential increase in processing speed as I add new Messaging nodes. With the POJO read process on its own blade, and 2 JBoss nodes on a blade each, I can queue almost 3000 messages per minute! In our previous implementation with MQ, we could only get 500 a minute!

        • 16. Re: MQ migration help
          tnine

          I have one final question regarding Dead Letter Queues. I have configured both my statement input and statement output queues to use a specific DLQ. Sometimes our MDBs are given invalid data, usually due to file charset issues, and I'd like to be notified processing fails so we can fix the input. When I fed our MDB invalid input I saw the following behavior.



          1. Send 4 messages to the queue StatementInput. 2 are valid 2 are not.

          2. The MDB processes 2 messages, and throws exceptions on processing the 2 invalid messages. As a result, these 2 messages should go in to the StatementDLQ

          3. At this point, I go to the JMX console and view the information on both the DLQ and StatementDLQ. StatementDLQ has a message count of 0, but DLQ has a message count of 2. This seems to be the opposite of what I'd expect

          4. Start the process that syncrhonously reads from the StatementDLQ queue. The first time it tries to consume messages with the receiveNoWait() method null is returned. This makes sense given that the JMX console says there are no messages in StatementDLQ

          5. When the Queue monitor wakes up for its second pass 30 seconds later, it receives 2 messages from the queue StatementDLQ. I don't understand this, since the JMX console says there are no messages in the queue.



            Perhaps I'm missing the point, but after step 2, should StatementDLQ have a MessageCount of 2 and DLQ have a MessageCount of 0? Below is my configuration from my destinations-service.xml file.

             <!-- Input Queue for statements -->
             <mbean code="org.jboss.jms.server.destination.QueueService"
             name="jboss.messaging.destination:service=Queue,name=StatementInput"
             xmbean-dd="xmdesc/Queue-xmbean.xml">
             <depends optional-attribute-name="ServerPeer">
             jboss.messaging:service=ServerPeer
             </depends>
             <depends>jboss.messaging:service=PostOffice</depends>
             <attribute name="DLQ">
             jboss.messaging.destination:service=Queue,name=StatementDLQ
             </attribute>
             <attribute name="Clustered">true</attribute>
             <attribute name="MaxDeliveryAttempts">2</attribute>
             <attribute name="FullSize">100</attribute>
             <attribute name="PageSize">50</attribute>
             <attribute name="DownCacheSize">50</attribute>
            
             </mbean>
            
             <mbean code="org.jboss.jms.server.destination.QueueService"
             name="jboss.messaging.destination:service=Queue,name=StatementOutput"
             xmbean-dd="xmdesc/Queue-xmbean.xml">
             <depends optional-attribute-name="ServerPeer">
             jboss.messaging:service=ServerPeer
             </depends>
             <depends>jboss.messaging:service=PostOffice</depends>
             <attribute name="DLQ">
             jboss.messaging.destination:service=Queue,name=StatementDLQ
             </attribute>
             <attribute name="Clustered">true</attribute>
             <attribute name="FullSize">100</attribute>
             <attribute name="PageSize">50</attribute>
             <attribute name="DownCacheSize">50</attribute>
             </mbean>
            
            
             <!-- DLQ for statements -->
             <mbean code="org.jboss.jms.server.destination.QueueService"
             name="jboss.messaging.destination:service=Queue,name=StatementDLQ"
             xmbean-dd="xmdesc/Queue-xmbean.xml">
             <depends optional-attribute-name="ServerPeer">
             jboss.messaging:service=ServerPeer
             </depends>
             <depends>jboss.messaging:service=PostOffice</depends>
             <attribute name="Clustered">true</attribute>
             <attribute name="FullSize">100</attribute>
             <attribute name="PageSize">50</attribute>
             <attribute name="DownCacheSize">50</attribute>
             </mbean>
            


          • 17. Re: MQ migration help
            clebert.suconic

             

            I can queue almost 3000 messages per minute!



            That's great!

            I should wait to tell you this.. but I can't wait! :-) We are working on JBM2, and on my poor Linux Laptop, using native LibAIO I'm doing 25000 persistent messages / second, on a size of 1K each one, which is pretty much my disk limit. We are now setting up a bigger hardware to do more tests. JBM 2 will rock in performance! :-)


            Regarding the DLQ, have you configured the DLQ attributes? (MaxDeliveryAttempts, RedeliveryDelay and others things like that?)


            Default configs at:
            http://www.jboss.org/file-access/default/members/jbossmessaging/freezone/docs/userguide-1.4.1.Beta1/html_single/index.html

            Also, look at queue configs at:
            6.7.2.1.3. DLQ,
            6.7.2.1.4. ExpiryQueue,
            6.7.2.1.6. MaxDeliveryAttempts





            • 18. Re: MQ migration help
              tnine

              Great! I'm looking forward to deploying it. Check out the 2 queue definitions in my last post, StatementInput and StatementOutput. Statement output never fails, it just dumps data to disk, so I'm not worried that worried about its DLQ. In the event of a read failure, the program halts immediately. However I have defined its DLQ as StatementDLQ just to be safe. In regards to my StatementInput Queue, I set the DLQ to StatementDLQ, and set the MaxDeliveryAttempts to 2 since I don't want 10 retries. If the delivery off of StatementInput fails once, it will most likely fail the second time. I don't want the messages to expire, so I didn't set the ExpiryQueue property. I followed the configuration examples in the destinations-service.xml file. Did I configure the DLQ attributes incorrectly?

              • 19. Re: MQ migration help
                clebert.suconic

                I have no idea what's going on...


                Can you run some basic DLQ test? If you still see a problem, maybe you should write a testcase.

                • 20. Re: MQ migration help
                  tnine

                  Sure thing. Do you have an existing test you would prefer I use as a template for connections, set up etc?

                  • 21. Re: MQ migration help
                    clebert.suconic

                    The mdb-failure is a good start.

                    • 22. Re: MQ migration help
                      tnine

                      One last quick question before I start. I want to make sure I'm not misunderstanding the J2EE 1.4 implementation details of an MDB.

                      What I expect
                      My MDB reads from the StatementInput queue. It fails to process the message, and the transaction is rolled back. After 2 failed read attempts on a message, it should go into the dead letter queue. In my configuration, this will be the StatementDLQ

                      What's happening
                      My MDB reads from StatementInput queue. It processes 2 messages, and 2 messages fail. However, with a clean system, the message count of StatementDLQ is 0, but the message count of DLQ is 2. This is equal to the number of failed messages.


                      Should all failures of MDB's end up in default queue/DLQ regardless of configuration? I read the J2EE 1.4 and JMS 1.1 spec, but I couldn't find anything in the exception documentation that outlines DLQ requirements.

                      Thanks,
                      Todd

                      • 23. Re: MQ migration help
                        tnine

                        I haven't forgotten about this, but I have had to put it off while working on production issues. I'm now reading from the DLQ, however I'm getting very erratic behavior. Somtimes a read with "receiveNoWait" will return messages on the DLQ, other times I'll have to call it 4 or 5 times before I receive a message, and the message count is > than 0 then viewing the queue on the jmx-console. I've attached my inner class that manages connections, am I calling something incorrectly? I'm looking up the connectionFactory via a remote JNDi, location "ClusteredXAConnectionFactory". Any help/advice would be appreciated.

                        
                        /**
                         * Inner class to manage connections per thread
                         *
                         * @author Todd Nine
                         *
                         */
                         private class SynchronousConnectionFactory {
                        
                         private final Logger connectionLogger = Logger
                         .getLogger(SynchronousConnectionFactory.class);
                        
                         // instance beans
                         private QueueConnection connection;
                         private QueueSession session;
                        
                         //pointers passed in during initialization and injection
                         private QueueConnectionFactory globalQueueConnectionFactory;
                         private Queue globalQueue;
                         private QueueReceiver receiver;
                        
                         /**
                         * Default constructor
                         *
                         * @param connectionFactory
                         * @param queue
                         */
                         public SynchronousConnectionFactory(
                         QueueConnectionFactory connectionFactory, Queue queue) {
                         this.globalQueueConnectionFactory = connectionFactory;
                         this.globalQueue = queue;
                         }
                        
                         /**
                         * Open the connection to the JMS queue
                         *
                         * @throws JMSException
                         */
                         public void openConnection() throws JMSException {
                         connection = getConnection();
                        
                         // create a session that we manually acknowledge so we can ignore
                         // messages that
                         // don't have the correct payload
                         session = connection.createQueueSession(false,
                         Session.CLIENT_ACKNOWLEDGE);
                        
                         receiver = session.createReceiver(this.globalQueue);
                        
                         connection.start();
                         }
                        
                         /**
                         * Return the message from the jms queue
                         *
                         * @return
                         * @throws JMSException
                         */
                         public Message getMessage() throws JMSException {
                         return receiver.receiveNoWait();
                         }
                        
                         /**
                         * Close the queue connection
                         *
                         * @param connection
                         */
                         public void closeReceiver() {
                         try {
                        
                        
                         if (session != null) {
                         session.close();
                         }
                        
                         if (connection != null) {
                         connection.close();
                         }
                         } catch (JMSException e) {
                         connectionLogger.warn("Could not close JMS connection", e);
                         }
                         }
                        
                         /**
                         * Get the connection from the factory
                         *
                         * @return
                         * @throws JMSException
                         */
                         protected QueueConnection getConnection() throws JMSException {
                         return globalQueueConnectionFactory.createQueueConnection();
                         }
                        
                         }


                        • 24. Re: MQ migration help
                          tnine

                          One quick note, I only get this when running in a cluster with 2 nodes. Both nodes share a DB, and I have set the ServerPeerID to 0 and 1 for nodes 1 and 2 respectively. I have also changed the queue/DLQ definition to the following.



                           <mbean code="org.jboss.jms.server.destination.QueueService"
                           name="jboss.messaging.destination:service=Queue,name=DLQ"
                           xmbean-dd="xmdesc/Queue-xmbean.xml">
                           <depends optional-attribute-name="ServerPeer">
                           jboss.messaging:service=ServerPeer
                           </depends>
                           <depends>jboss.messaging:service=PostOffice</depends>
                           <attribute name="Clustered">true</attribute>
                           </mbean>
                          
                          


                          • 25. Re: MQ migration help
                            timfox

                             

                            "tnine" wrote:
                            I haven't forgotten about this, but I have had to put it off while working on production issues. I'm now reading from the DLQ, however I'm getting very erratic behavior. Somtimes a read with "receiveNoWait" will return messages on the DLQ, other times I'll have to call it 4 or 5 times before I receive a message, and the message count is > than 0 then viewing the queue on the jmx-console. I've attached my inner class that manages connections, am I calling something incorrectly?


                            receiveNoWait semantics are commonly misunderstood.

                            Search for receiveNoWait in the forums for several threads on this subject and and explanation of what you are seeing.

                            • 26. Re: MQ migration help
                              tnine

                              Thanks for the help. I found this post, and it really helped me understand how I can best utilize the changes in JBoss Messaging.

                              http://www.jboss.com/index.html?module=bb&op=viewtopic&t=71350

                              Basically, all I did was change 2 things in my code. I now have my connection object created and opened when my DLQ observer class is instantiated, rather than creating and disconnecting a session when the observer is called. This allows my connection to exist through the entire execution of the client, and thus allows for async client buffering. Once I made the change to connection, I then replaced receiveNoWait with receive(2000). Even if a message isn't available when the observer is called the first time, I always have messages from the queue by the 2nd execution 30 seconds later.

                              • 27. Re: MQ migration help
                                konami

                                 

                                "tnine" wrote:


                                Steps to migrate DefaultDS to MySQL and set up messaging.


                                1. Download the latest MySQL client jar and put it in server/lib
                                2. Set up the following in a mysql-ds.xml file, and remove the hsqldb-ds.xml file


                                  <datasources>
                                   <local-tx-datasource>
                                   <jndi-name>DefaultDS</jndi-name>
                                   <connection-url>
                                   jdbc:mysql://localhost:3306/jboss
                                   </connection-url>
                                   <driver-class>com.mysql.jdbc.Driver</driver-class>
                                   <user-name>jboss</user-name>
                                   <password>password</password>
                                   <exception-sorter-class-name>
                                   org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter
                                   </exception-sorter-class-name>
                                   <metadata>
                                   <type-mapping>mySQL</type-mapping>
                                   </metadata>
                                   <!-- Required for Messaging to work correctly -->
                                   <transaction-isolation>
                                   TRANSACTION_READ_COMMITTED
                                   </transaction-isolation>
                                   </local-tx-datasource>
                                  
                                  </datasources>
                                  


                                3. Download the messaging distribution that has the same version as the one in your application server. For the JEMS 1.2.1.CR4 installer, I installed messaging version 1.4.0.SP3 (build: CVSTag=JBossMessaging_1_4_0_
                                  SP3 date=200712131418)

                                4. Copy mysql-persistence-service.xml from examples/config of your messaging download to server/deploy/jboss-messaging.sar, and either delete or rename hsqldb-persistence-service.xml.bak

                                5. Restart the server, and everything should work!



                                Thanks for the tip. It worked for me.

                                1 2 Previous Next