Reputation: 1449
I recently started learning JMS and so far understood some of the concepts. However I would like to know how IBM MQ or any queue provider handles request from a multithreaded application. for example
Consider a application which is mutithreaded and configured to send messages to Mainframe host using MQ. This application has one Put queue and get queue configured. Imagine 10 requests are getting processed each wanting to get data from the host. Since Queue is just one, all these 10 messages are placed in the queue simultaneously.The host processes the messages and sends the reply to the client i.e. the application. How does the reply messages don't get mixed up and every thread gets its own correct reply message?
Some id is used while communicating and is it specific to a particular thread of message sent? Does a JMS session needs to be established for each new thread of execution.? What is same session is used for all 10 requests? Will appreciate any examples or links which explains this concept in detail.
Upvotes: 3
Views: 3961
Reputation: 22279
JMS supports this with a couple of features:
First, the JMSCorrelationId is a JMS header that is used to correlate a request with a response. I.e. each message contains a globally unique (GUUID) JMSMessageId. The mainframe app should simply copy the message id from the request to the JMSCorrelationId on the response message and send back to the shared response queue.
So, simply send a request by:
(psuedo code - in one thread, do the following when you need to request data over JMS)
myMessage = session.createTextMessage("My nice request");
messageProducer.send(myMessage); // using some previously setup producer
// commit if needed
mc = session.createConsumer(queue,"JMSCorrelationId='"+myMessage.getMessageId()+"'");
responseMessage = mc.receive(TIMEOUT);
if( responseMessage != null){
//got OUR response data
}
// close down consumer here.
The trick to allow multiple consumer threads (or applications) is the Selector in the consumer. A JMS selector is similar to a sub set of SQL or similar query languages. In this case just select messages where the JMSCorrelationId is the same as the id in the request send some time back.
This is the only "safe" setup that you can do with the contraints that you have one fixed, shared queue and that a request must come back to the very same thread it was requested from.
To avoid the overhead of JMS Selectors you could otherwise use temporary queues for the replies, one temp queue per request, then there will be no other thread listening for a specific response. Another option to gain performance is to make the application more asynchronous. JMS actually promotes this, fire off a request, and let a pool of consumer threads deal with any asyncrhonous responses - each thread is equally capable of dealing with any reponse - usch as processing the data and putting it into a database (or similar). I don't know if this design paradigm is applicable to your case, but you should be aware of it at least.
Upvotes: 3