-
2. Re: Confusion on how to use ClientSessionFactory...
unsavory Apr 29, 2010 11:28 PM (in response to gaohoward)Thanks for the link. However, from your comment at the bottom...
i think it's very clear. One thing should be noted is when you reuse sessions, be aware of the thread safe issue. JMS doesn't guarantee session's thread safety.
So if my producers are running inside a web application with multiple threads, how could I possibly re-use the sessions if they are not thread-safe? In this situation, should I be creating new sessions for each request?
-
3. Re: Confusion on how to use ClientSessionFactory...
gaohoward Apr 29, 2010 11:34 PM (in response to unsavory)I think that needs some work to solve this. for example, you can create a class dedicated to messaging sending/receiving. Instead of handling the messaging related task directly inside a request, you put the messaging related task to the dedicated class, which can cache the session and synchronize the message handling. or you can keep a session per thread and handle messaging concurrently.
-
4. Re: Confusion on how to use ClientSessionFactory...
gaohoward Apr 29, 2010 11:45 PM (in response to gaohoward)1 of 1 people found this helpfulPreferrably you can use JCA, as desribed in the wiki.
-
5. Re: Confusion on how to use ClientSessionFactory...
unsavory Apr 30, 2010 12:23 AM (in response to gaohoward)Thanks for the suggestions. I would say the JBoss documentation is misleading then if it says...
If you're using just raw JMS - i.e you have a simple JMS client which connects directly to a JMS server using the JMS API, then you should always re-use JMS objects.
JMS objects like connection, session, consumer and producer were designed to be re-used.
The information may be factual, but nowhere does it say or imply that the JMS objects are not thread-safe and should be treated with care in highly concurrent environments.
I'm not running in a JEE appserver so do not have JCA available that I know of unless there is some way to configure a JCA provider inside Tomcat. I suppose synchronization might work but it would severely impact multi-threaded performance.
-
6. Re: Confusion on how to use ClientSessionFactory...
unsavory Apr 30, 2010 12:40 AM (in response to unsavory)As I think about this, perhaps I could initialize the factories and client sessions inside my servlet's init method?
-
7. Re: Confusion on how to use ClientSessionFactory...
timfox Apr 30, 2010 5:33 AM (in response to unsavory)Caine Lai wrote:
All the examples seem to create new sessions every time a message is published or consumed. Such as below:
ClientSessionFactory factory = HornetQClient.createClientSessionFactory(
new TransportConfiguration(
InVMConnectorFactory.class.getName()));ClientSession session = factory.createSession();
session.start();
ClientConsumer consumer = session.createConsumer("example");
boolean run = true;
while(run) {
ClientMessage msgReceived = consumer.receive();
// Important... acknowledge message.
msgReceived.acknowledge();
System.out.println("message = " + msgReceived.getStringProperty("msg"));
}
session.close();If I am consuming thousands of messages, do I want to create, start and close the session each time? Or perform it all within the same session?
And in the case of producers, should all the producers use the same ClientSession? Or use the ClientSessionFactory to create a new session for each message?
Read the performance tuning section in the user manual.
Session, consumers, producers etc should always be re-used. It is a classic *anti-pattern* to create them each time. This has also been discussed many times on other threads.
There's also a wiki page that touches on this (should i use spring jms template)
The examples are ok, since they only send a single message.
-
8. Re: Confusion on how to use ClientSessionFactory...
timfox Apr 30, 2010 5:37 AM (in response to unsavory)Caine Lai wrote:
So if my producers are running inside a web application with multiple threads, how could I possibly re-use the sessions if they are not thread-safe?
Re-using sessions has nothing to do with thread safety.
The following code re-uses a session and a producer to send 1000 messages
Session session = connection.createSession(..);
MessageProducer prod = session.createProducer(...);
for (int i = 0; i < 1000; i++)
{
prod.send(session.createMessage());
}
You can also maintain references to your session, consumers, producers etc and pass them around your application, you just need to make sure they are not used *concurrently*.
-
9. Re: Confusion on how to use ClientSessionFactory...
timfox Apr 30, 2010 5:39 AM (in response to unsavory)Caine Lai wrote:
The information may be factual, but nowhere does it say or imply that the JMS objects are not thread-safe and should be treated with care in highly concurrent environments.
It's in the JMS spec. Section 4.4.6:
"Sessions are designed for serial use by one thread at a time."
-
10. Re: Confusion on how to use ClientSessionFactory...
timfox Apr 30, 2010 5:42 AM (in response to unsavory)Caine Lai wrote:
So if my producers are running inside a web application with multiple threads, how could I possibly re-use the sessions if they are not thread-safe? In this situation, should I be creating new sessions for each request?
No, do not create new sessions for each request.
If you are running tomcat in JBoss then you can just use the JCA adaptor - it DOES work in the embedded tomcat.
If you are using Tomcat outside JBoss use a pool to cache sessions, producers etc. The checkout + return semantics of the pool will ensure the session is never used by more than one thread concurrently.
-
11. Re: Confusion on how to use ClientSessionFactory...
timfox Apr 30, 2010 5:43 AM (in response to timfox)You can also use the Spring message listener container in tomcat
-
12. Re: Confusion on how to use ClientSessionFactory...
unsavory Apr 30, 2010 6:30 AM (in response to timfox)First Tim, thank you very much for taking the time. Your answers have given a lot of insight into how I should go about implementing this. I do have some questions though.
You can also maintain references to your session, consumers, producers etc and pass them around your application, you just need to make sure they are not used *concurrently*.
OK, got it. But I still have a question around session.start and session.end. Do I maintain the reference to a session throughout my application and call session.start() and session.end() for each sent message? Or do I call session.start() on application startup, and session.end() on application shutdown?
It's in the JMS spec. Section 4.4.6:
"Sessions are designed for serial use by one thread at a time."
OK, but I am not using JMS. I am using the HornetQ API. Isn't JMS a layer on top of the HornetQ API? How is one to know that the HornetQ API is not thread-safe by looking at the JMS spec?
If you are using Tomcat outside JBoss use a pool to cache sessions, producers etc. The checkout + return semantics of the pool will ensure the session is never used by more than one thread concurrently.
Yes, I am using Tomcat outside Jboss. I will definitely look into creating a pool, however because I don't have any experience with HornetQ, I am a bit concerned around what gotchas I would have to watch out for with the pool. In other words, do I ever need to re-create a new session under some circumstances? Would sessions ever die unexpectedly leaving me with a bad pool thread? Etc., Etc.
You can also use the Spring message listener container in tomcat
Again, I'm not using JMS. Should I be? I was going to use the HornetQ API for simplicity. Also, my message listener will be a single thread since I need to process messages in the order they are received. It is the message producers that need to be multi-threaded.
Given this, does it sound like the thread pool approach would be the best way to go? Or would it be simpler to use something like a thread-local instance of ClientProducer for my servlets?
Thanks again for your helpful responses.
-
13. Re: Confusion on how to use ClientSessionFactory...
timfox Apr 30, 2010 10:31 AM (in response to unsavory)I assumed you were using JMS since you were talking about using JCA which of course only works with JMS.
-
14. Re: Confusion on how to use ClientSessionFactory...
unsavory Apr 30, 2010 11:52 AM (in response to timfox)Sorry about the confusion. Yong suggested I use JCA, so I was responding to that. I am not apposed to using JMS if there is a reason to do it, but our needs are pretty simple so was hoping to stay with the HornetQ API.