9 Replies Latest reply on Nov 15, 2007 1:40 PM by dolanp

    Connection caching

    dolanp

      Hello all. We are currently using Spring heavily in our development and are also trying to migrate to JBoss with JBoss Messaging as our JMS delivery system. I have seen the article on the wiki by Tim Fox that recommends against using JMSTemplate in general with JBoss Messaging and I was wondering if there is a preferred or recommended way of reliably caching connections for JMS. We have run into some trouble using some of the Spring JMS functionality already and we are considering writing our own connection caching system if there is not already an availble open source system that does this. I looked a bit at Jencks but it looks like it is geared more towards ActiveMQ. Can that be integrated with JBoss Messaging easily?

      Thanks for any suggestions and/or information!

        • 1. Re: Connection caching
          timfox

          Are you talking about usage inside the app server, or outside the app server - e.g. in your own client programs?

          • 2. Re: Connection caching
            dolanp

            This would be from outside the application server, clients that connect.

            • 3. Re: Connection caching
              timfox

              Are you using Spring JMSTemplate currently just to send messages, or to consume them too?

              • 4. Re: Connection caching
                dolanp

                We use the DefaultMessageListenerContainer to consume messages.

                • 5. Re: Connection caching
                  travisb

                  There is only one case where we use JmsTemplate to consume messages, and that is for the purpose of aggregation. For that case we may use jmsTemplate.execute(SessionCallback action, boolean startConnection) to circumvent the resource impact of jmsTemplate.receive().

                  We also use JmsTemplate as a producer outside the app server. Once we determine an appropriate caching solution, we will apply it to both the JmsTemplate senders and the various DefaultMessageListenerContainer deployments.

                  • 6. Re: Connection caching
                    travisb

                    The DefaultMessageListenerContainer relates to the JmsTemplate in that it is equally resource intensive with a cache level of CACHE_NONE. Our client works with CACHE_CONSUMER, but with a level of CACHE_SESSION or less, consumption halts and we quickly receive the following stacktrace in the server logs:

                    ERROR [org.jboss.logging.Log4jService$ThrowableListenerLoggingAdapter] Unhandled Throwable
                    org.jboss.util.threadpool.ThreadPoolFullException: java.lang.RuntimeException: Pool is blocked
                    at org.jboss.util.threadpool.BasicThreadPool.execute(BasicThreadPool.java:417)
                    at org.jboss.util.threadpool.BasicThreadPool.runTaskWrapper(BasicThreadPool.java:192)
                    at org.jboss.util.threadpool.BasicThreadPool.run(BasicThreadPool.java:212)
                    at org.jboss.util.threadpool.BasicThreadPool.run(BasicThreadPool.java:206)
                    at org.jboss.util.timeout.TimeoutFactory.doWork(TimeoutFactory.java:223)
                    at org.jboss.util.timeout.TimeoutFactory.access$000(TimeoutFactory.java:41)
                    at org.jboss.util.timeout.TimeoutFactory$1.run(TimeoutFactory.java:136)



                    When using CACHE_CONSUMER, the DMLC fails to recover when JBoss is recycled. Logs will indicate a successful recovery, but the DMLC will continue to receive null even though messages are available on the queue.


                    • 7. Re: Connection caching
                      timfox

                      Inside the app server you can use the JBoss JCA resource adapter (the thing at /JmsXA - see the user wiki) for caching sessions.

                      This is useful when you're for example sending messages from an EJB.

                      Note that JCA JMS resource adapters do not cache JMS connections, they cache JMS sessions.,

                      Caching JMS connections won't be much use to you, since you don't want to be creating a new session every time you send a message (slow). Creating a producer every time you send a message (which would happen with JmsXA) is not so bad since mesage producers are typically lightweight objects created only on the client side - although of course there is some overhead even with that.

                      On the client side the JBoss JMS resource adapter won't work. But then, if you handle connection creation and closing sensibly in your own code there should be no need for caching connections/sessions/consumers.

                      Personally I dislike these caching layers since they encourage bad programming habits and cover a multitude of sins.

                      At the end of the day in order to use JMS optimally you need to have a good understanding of the relationship between connection, session, consumer and producer objects and use them appropriately.

                      You may be able to get something like Jencks to work for you on the client side. AFAIK this is an alternative JCA adapter. But be warned, as mentioned before, these will only cache JMS sessions, so you'll still be creating a producer / consumer each time, and you have to be careful to avoid losing messages due to consumers being transiently created/closed.

                      My advice, avoid Spring JMSTemplate altogether and don't use caching, apart from on the app server for sending messages (for receiving you could use MDBs)

                      • 8. Re: Connection caching
                        dolanp

                        Thanks for your insight Tim. Last night I configured my DMLC to use Spring's JmsTransactionManager and it seems to do a lot better at politely taking care of resources. In the default configuration it was hammering JBoss and causing it to run out of thread pools and become defunct but now it is behaving normally and efficiently. We are going to try to recode some of our stuff that uses JMSTemplate for sending just to be safe.

                        • 9. Re: Connection caching
                          dolanp

                          Just to give an update to this in case anyone else has a similar issue with the JMSTemplate. It appears that Spring's recommended solution for caching the actual connection is to wrap your connection factory in the Spring SingleConnectionFactory object. This will share the connection across multiple sends and is much better performing. It still doesn't seem possible to cache at the session level but it's possible that the next release of Spring might address it.