Re: Question about JMS Session Pool
Ulhas Bhole schrieb: I think this behaviour is not implemented in any of the Connection Pools I know. So my question here is how would we implement this with a JMSTemplate. Without any further configuration the JMSTemplate even with SingleConnectionFactory would create a new Session, Producer, Temporary Queue and Consumer for each message. I am not sure if this is acceptable. I think we should get away from creating temporary queue each time. I think it is acceptable to have one temp queue serving as replyDestination if no replyDestination is explicitly set. The default behavior CXF states should be like " JMS transport will use temporary queue if no replyDestination is specified" which can be implemented as one temporary queue or pool of temporary queues (with listener for each) or the current way (which is highly discouraged as far as I got the feedback). As far as I know the current way is a pool of temporary queues. So I guess the performance is quite good. I only do not know how to easily set this up with Spring JMS. I also wonder how much performance a pool of temporary queues gives you compared to one single listening thread on a single temporary queue that dispatches to a threadpool after it has received the JMS message. My guess is that the jms receive is quite fast and dispatching to a threadpool could be almost as fast as having a pool of listeners in the first place. One idea I have is to Simply create one or more listenerthreads with consumers on the replyDestination. They would then receive the responses completely asynchronous and we could find the right exchange by using the correlationId. One issue with this idea is that we can only have one Thread on a temporary queue as the queue is only visible to the Session that created the queue. (At least I think so). Any ideas for this? Currently, for request/reponse MEP we set JMSMessageID as correlationID so it should not be difficult to implement the correlate response (we can maintain hashmap or some collection which would hold the Request Exchange keyed using JMSMessageID when the message is sent however, I think we will need to look into what will happen to the JAX-WS request and response context which when last I knew were thread local becuse we pump in JMS_REPONSE_HEADERS into it. My colleague Edaurd also told me that there is a correlation interceptor. Does this interceptor perhaps already do all we need? I just remembered that we could have another problem with listener threads on a permanent reply queue. If we have two machines listening on the same queue but not with a single Messageselector (as they wait for several messages) they can not know for which machine a message on the reply queue is. Best regards Christian -- Christian Schneider --- http://www.liquid-reality.de
Re: Question about JMS Session Pool
Hi Christian, comments inline... -- Ulhas Christian Schneider wrote: Guillaume Nodet schrieb: Commons-pool is not a JMS connection pool. I was mostly thinking about the ActiveMQ one, but i think each JMS provider should have its own connection pool. In a Java EE environment, the connection pool is done by the server and you don't have to think about it. Anyway, it's part of the ConnectionFactory set up by the user, so the CXF code should not really take care of it. I think you are right that CXF should not take care of it. But in case the user does not run the application in an appserver he will need a connection pool that he can configure as a wrapper on his ConnectionFactory. I guess the ActiveMQ pooling is not useable for other providers? The Spring CachingConnectionFactory is described here: http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/jms/connection/CachingConnectionFactory.html http://static.springframework.org/spring/docs/2.5.x/reference/jms.html#jms-connections In the second link they detail that for a JMStemplate in a standalone environment the SingleConnectionFactory should be used to avoid opening a connection on every call to the template. Currently the JMSConduit works in the following way. It fetches a PooledSession from the SessionFactory. The PooledSession contains already initialized Session, MessageProducer and MessageConsumer. If the reply queue is temporary each pooled session has a different already created temporary Queue that is reused each time the PooledSession is fetched. Then it sends out a message to the targetDestination and sets the replyDestination from the pooledSession as replyTo. After that it waits synchronously with a consumer on the replyDestination for the reply to come. I think this behaviour is not implemented in any of the Connection Pools I know. So my question here is how would we implement this with a JMSTemplate. Without any further configuration the JMSTemplate even with SingleConnectionFactory would create a new Session, Producer, Temporary Queue and Consumer for each message. I am not sure if this is acceptable. I think we should get away from creating temporary queue each time. I think it is acceptable to have one temp queue serving as replyDestination if no replyDestination is explicitly set. The default behavior CXF states should be like " JMS transport will use temporary queue if no replyDestination is specified" which can be implemented as one temporary queue or pool of temporary queues (with listener for each) or the current way (which is highly discouraged as far as I got the feedback). One idea I have is to Simply create one or more listenerthreads with consumers on the replyDestination. They would then receive the responses completely asynchronous and we could find the right exchange by using the correlationId. One issue with this idea is that we can only have one Thread on a temporary queue as the queue is only visible to the Session that created the queue. (At least I think so). Any ideas for this? Currently, for request/reponse MEP we set JMSMessageID as correlationID so it should not be difficult to implement the correlate response (we can maintain hashmap or some collection which would hold the Request Exchange keyed using JMSMessageID when the message is sent however, I think we will need to look into what will happen to the JAX-WS request and response context which when last I knew were thread local becuse we pump in JMS_REPONSE_HEADERS into it. Best regards Christian IONA Technologies PLC (registered in Ireland) Registered Number: 171387 Registered Address: The IONA Building, Shelbourne Road, Dublin 4, Ireland
Re: Question about JMS Session Pool
Guillaume Nodet schrieb: Commons-pool is not a JMS connection pool. I was mostly thinking about the ActiveMQ one, but i think each JMS provider should have its own connection pool. In a Java EE environment, the connection pool is done by the server and you don't have to think about it. Anyway, it's part of the ConnectionFactory set up by the user, so the CXF code should not really take care of it. I think you are right that CXF should not take care of it. But in case the user does not run the application in an appserver he will need a connection pool that he can configure as a wrapper on his ConnectionFactory. I guess the ActiveMQ pooling is not useable for other providers? The Spring CachingConnectionFactory is described here: http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/jms/connection/CachingConnectionFactory.html http://static.springframework.org/spring/docs/2.5.x/reference/jms.html#jms-connections In the second link they detail that for a JMStemplate in a standalone environment the SingleConnectionFactory should be used to avoid opening a connection on every call to the template. Currently the JMSConduit works in the following way. It fetches a PooledSession from the SessionFactory. The PooledSession contains already initialized Session, MessageProducer and MessageConsumer. If the reply queue is temporary each pooled session has a different already created temporary Queue that is reused each time the PooledSession is fetched. Then it sends out a message to the targetDestination and sets the replyDestination from the pooledSession as replyTo. After that it waits synchronously with a consumer on the replyDestination for the reply to come. I think this behaviour is not implemented in any of the Connection Pools I know. So my question here is how would we implement this with a JMSTemplate. Without any further configuration the JMSTemplate even with SingleConnectionFactory would create a new Session, Producer, Temporary Queue and Consumer for each message. I am not sure if this is acceptable. One idea I have is to Simply create one or more listenerthreads with consumers on the replyDestination. They would then receive the responses completely asynchronous and we could find the right exchange by using the correlationId. One issue with this idea is that we can only have one Thread on a temporary queue as the queue is only visible to the Session that created the queue. (At least I think so). Any ideas for this? Best regards Christian -- Christian Schneider --- http://www.liquid-reality.de
Re: Question about JMS Session Pool
Commons-pool is not a JMS connection pool. I was mostly thinking about the ActiveMQ one, but i think each JMS provider should have its own connection pool. In a Java EE environment, the connection pool is done by the server and you don't have to think about it. Anyway, it's part of the ConnectionFactory set up by the user, so the CXF code should not really take care of it. On Wed, Sep 3, 2008 at 7:23 PM, Christian Schneider <[EMAIL PROTECTED]> wrote: > Guillaume Nodet schrieb: >> >> The Spring JMS layer contains two parts: the JmsTemplate which can be >> used to send / consume messages, and the MessageListenerContainers >> that can be used to consumer messages more efficiently. Caching is >> configurable on the DefaultMessageListenerContainer, but the >> JmsTemplate doesn't do caching, mainly because it is meant to work in >> a Java EE environment, where the client is supposed to create a >> connection / session / sender every time. Thus, a really good thing >> is to configure a JMS pooled connection factory underneath (see >> http://activemq.apache.org/spring-support.html). >> >> >> > > Hi Guillaume, > > what connection pooling do you use? I know there is one implementation in > http://commons.apache.org/pool/. Spring also contains Pooled Session > Factories but there > are several... Which would you suggest to use? > > Best regards > > Christian > > -- > > Christian Schneider > --- > http://www.liquid-reality.de > > -- Cheers, Guillaume Nodet Blog: http://gnodet.blogspot.com/
Re: Question about JMS Session Pool
Guillaume Nodet schrieb: The Spring JMS layer contains two parts: the JmsTemplate which can be used to send / consume messages, and the MessageListenerContainers that can be used to consumer messages more efficiently. Caching is configurable on the DefaultMessageListenerContainer, but the JmsTemplate doesn't do caching, mainly because it is meant to work in a Java EE environment, where the client is supposed to create a connection / session / sender every time. Thus, a really good thing is to configure a JMS pooled connection factory underneath (see http://activemq.apache.org/spring-support.html). Hi Guillaume, what connection pooling do you use? I know there is one implementation in http://commons.apache.org/pool/. Spring also contains Pooled Session Factories but there are several... Which would you suggest to use? Best regards Christian -- Christian Schneider --- http://www.liquid-reality.de
Re: Question about JMS Session Pool
The Spring JMS layer contains two parts: the JmsTemplate which can be used to send / consume messages, and the MessageListenerContainers that can be used to consumer messages more efficiently. Caching is configurable on the DefaultMessageListenerContainer, but the JmsTemplate doesn't do caching, mainly because it is meant to work in a Java EE environment, where the client is supposed to create a connection / session / sender every time. Thus, a really good thing is to configure a JMS pooled connection factory underneath (see http://activemq.apache.org/spring-support.html). On Wed, Sep 3, 2008 at 4:53 PM, Daniel Kulp <[EMAIL PROTECTED]> wrote: > > Actually, one more note: > > He STRONGLY suggests not writing any JMS code in the JMS transport at all: > > dkulp: don't even think of writing any JMS code within cxf, just > use spring message listener container > you can configure the spring JMS stuff however you want > we use URIs in camel for example > seriously, delete your jms code, just use spring however you wanna > use it > > > I don't know all the details about it, but apparently if you use the Spring > jms/messaging stuff, it will work with the Spring transactions and security > and such which doesn't work with "pure jms" stuff. One reason we've seen > for not using our JMS and instead using Camel or Mule or similar is due to > the lack of spring transaction support. It might be a good idea to grab the > Camel and/or ServiceMix JMS code (probably Camel) and use that as more of a > starting point. > > Also, the latest public draft of the SOAP/JMS stuff is at: > http://www.w3.org/TR/2008/WD-soapjms-20080723/ > > > Dan > > > > On Wednesday 03 September 2008 10:23:42 am Daniel Kulp wrote: >> I just asked James Strachan and he said: >> >> dkulp: but yes, you've gotta cache sessions >> and consumers >> >> I don't know the details, but since he knows the insides of ActiveMQ pretty >> well, I'd take his advise. :-) >> >> Dan >> >> On Tuesday 02 September 2008 5:00:38 pm Christian Schneider wrote: >> > Hi, >> > >> > I am just working an a refactoring of the JMS Transport. In the module >> > there is an implementation of a session cache. >> > >> > As we later want to switch to SpringTemplate and Spring >> > ListenerContainer I want to get rid of as much pooling implementation as >> > possible. >> > So my question is: Do we really need a session cache. As far as I >> > understood from JMS specs sessions are lightweight short lived objects. >> > So I think it would not harm to create a new session for each message >> > and destroy it later. The same is true for producers. >> > >> > The connection on the other hand has to be cached as it is costly to >> > create. I think the connection could be stored as a simple attribute of >> > JMSConduit or JMSDestination. >> > As far as I know it is thread safe too. >> > >> > What is your knowledge about this? >> > >> > Best regards >> > >> > Christian > > > > -- > Daniel Kulp > [EMAIL PROTECTED] > http://www.dankulp.com/blog > -- Cheers, Guillaume Nodet Blog: http://gnodet.blogspot.com/
Re: Question about JMS Session Pool
Actually, one more note: He STRONGLY suggests not writing any JMS code in the JMS transport at all: dkulp: don't even think of writing any JMS code within cxf, just use spring message listener container you can configure the spring JMS stuff however you want we use URIs in camel for example seriously, delete your jms code, just use spring however you wanna use it I don't know all the details about it, but apparently if you use the Spring jms/messaging stuff, it will work with the Spring transactions and security and such which doesn't work with "pure jms" stuff. One reason we've seen for not using our JMS and instead using Camel or Mule or similar is due to the lack of spring transaction support. It might be a good idea to grab the Camel and/or ServiceMix JMS code (probably Camel) and use that as more of a starting point. Also, the latest public draft of the SOAP/JMS stuff is at: http://www.w3.org/TR/2008/WD-soapjms-20080723/ Dan On Wednesday 03 September 2008 10:23:42 am Daniel Kulp wrote: > I just asked James Strachan and he said: > > dkulp: but yes, you've gotta cache sessions > and consumers > > I don't know the details, but since he knows the insides of ActiveMQ pretty > well, I'd take his advise. :-) > > Dan > > On Tuesday 02 September 2008 5:00:38 pm Christian Schneider wrote: > > Hi, > > > > I am just working an a refactoring of the JMS Transport. In the module > > there is an implementation of a session cache. > > > > As we later want to switch to SpringTemplate and Spring > > ListenerContainer I want to get rid of as much pooling implementation as > > possible. > > So my question is: Do we really need a session cache. As far as I > > understood from JMS specs sessions are lightweight short lived objects. > > So I think it would not harm to create a new session for each message > > and destroy it later. The same is true for producers. > > > > The connection on the other hand has to be cached as it is costly to > > create. I think the connection could be stored as a simple attribute of > > JMSConduit or JMSDestination. > > As far as I know it is thread safe too. > > > > What is your knowledge about this? > > > > Best regards > > > > Christian -- Daniel Kulp [EMAIL PROTECTED] http://www.dankulp.com/blog
Re: Question about JMS Session Pool
I just asked James Strachan and he said: dkulp: but yes, you've gotta cache sessions and consumers I don't know the details, but since he knows the insides of ActiveMQ pretty well, I'd take his advise. :-) Dan On Tuesday 02 September 2008 5:00:38 pm Christian Schneider wrote: > Hi, > > I am just working an a refactoring of the JMS Transport. In the module > there is an implementation of a session cache. > > As we later want to switch to SpringTemplate and Spring > ListenerContainer I want to get rid of as much pooling implementation as > possible. > So my question is: Do we really need a session cache. As far as I > understood from JMS specs sessions are lightweight short lived objects. > So I think it would not harm to create a new session for each message > and destroy it later. The same is true for producers. > > The connection on the other hand has to be cached as it is costly to > create. I think the connection could be stored as a simple attribute of > JMSConduit or JMSDestination. > As far as I know it is thread safe too. > > What is your knowledge about this? > > Best regards > > Christian -- Daniel Kulp [EMAIL PROTECTED] http://www.dankulp.com/blog
Re: Question about JMS Session Pool
I have found one thing in the PooledSession that is probably worth keeping in a Cache. The Consumer which waits for reply messages. At the moment in the JMSConduit a request is sent out then the thread waits synchronously for a reply on the consumer of the pooled session. Wouldn´t it be possible to simply start one or more consumers permanently to listen for reply messages each in a ListenerThread and then correlate the reply messages to the request messages. So we do not need a pool as each listener will permanently have it´s own thread. Best regards Christian Christian Schneider schrieb: Hi, I am just working an a refactoring of the JMS Transport. In the module there is an implementation of a session cache. As we later want to switch to SpringTemplate and Spring ListenerContainer I want to get rid of as much pooling implementation as possible. So my question is: Do we really need a session cache. As far as I understood from JMS specs sessions are lightweight short lived objects. So I think it would not harm to create a new session for each message and destroy it later. The same is true for producers. The connection on the other hand has to be cached as it is costly to create. I think the connection could be stored as a simple attribute of JMSConduit or JMSDestination. As far as I know it is thread safe too. What is your knowledge about this? Best regards Christian -- Christian Schneider --- http://www.liquid-reality.de