I do some heavy traitement at reception of JMS message, with high risk of timeout.
whole point of using JMS for me is to allow this kind of computation to be done asynchronisely. ( I dont want my other consumer to block if one of them block, i dont want my producer to block, ever ). ideally, i also want my consumer to be able to receive second message during computation of first one
Right now, i'm using unique javax.jms.Session for sending, and consuming my message. I'm aware it was conception mistake. As doc state :
session can create and service multiple message producers and consumers.
But also :
If client desires to have one thread produce messages while others consume them, client should use separate session for its producing thread.
solution could be to use session for producer, and different session for each consumer, but consumers will still be able to handle only one message at time
For my understanding onMessage method is called by Jms Provider ( ActiveMq i开发者_StackOverflow中文版n my case ). Could any configuration allow this call to be call in several thread ?
Maybe this question is reflect of major flaw in my understanding of how JMS should be use / my conception. Please fell free to discuss ;)
Thanks !
Edit :
my problem in one sentence :
- if i have 2 consumer, and if one of them take long time to process onMessge, all other consumer will blocK.
What is done today : I'm using a java.util.concurent.Executor, but i'm not a big fan of this solution. I'm in a Tomcat application server context, and already using too much thread, i will like to delegate this responsability to a more robust bunch of code. ( Eg : activeMq )
Edit 2 :
More detail :
I dont use transactional session
I use Auto_Acknoledge
Your description is a hard to follow, and I don't think it's a language issue. My best understanding is that your producer is blocking because the consumer takes a long time to process the message. If true, this implies that you're using durable messages and explicit acknowledgment after processing the message.
And if that's the case, the two possible solutions are: (1) decide whether you really need the guarantees and use implicit acknowledgment and/or non-durable messages if not, or (2) reliably store the message in the consumer, acknowledge, and then process the message.
Based on your edits, the short answer is "yes, you can spawn threads." Since the producer doesn't care whether the consumer is able to actually process the message, you have a lot of flexibility in how you handle it.
I suspect that ActiveMQ has some property that would allow you to control the number of message-processing threads. I haven't used it extensively (prefer HornetQ), so can't give a definitive answer.
However, even if it does, I'd prefer using a Java ThreadPoolExecutorService
(I think that's the name of it; see java.util.concurrent
). The main reason is that it provides its own internal work queue. No matter how many threads you give to the messaging framework, there's always the possibility that you'll have enough work to tie them up. With the ExecutorService
, you will continue to receive and queue messages until you run out of memory (and if that happens, you have some design issues to resolve).
javax.jms.Session and below (MessageConsumer, MessageProducer) are single-threaded. If you want any multithreading, you want multiple Sessions. One Session per consumer.
Each consumer will be single-threaded. But a JMS implementation should be able to multi-thread message deliver between multiple consumers if they're created from multiple sessions.
You should simply cut down your heavy traitement into a process that can be handled into one transaction.
I can not help you since you don't mention what this traitement is about.
精彩评论