我最近开始学习JMS,到目前为止已经了解了一些概念.但是,我想知道IBM MQ或任何队列提供者如何处理来自多线程应用程序的请求.例如
考虑一个具有多线程并配置为使用MQ将消息发送到大型机主机的应用程序.此应用程序配置了一个放置队列和获取队列.想象一下,每个要从主机获取数据的请求都被处理了10个.由于Queue只是其中一个,因此所有这10条消息都同时放入队列中,主机会处理这些消息并将答复发送给客户端(即应用程序).回复消息如何不混淆,每个线程如何获得自己正确的回复消息?
通信时会使用一些ID,它是否特定于所发送消息的特定线程?是否需要为每个新的执行线程建立JMS会话?什么是相同的会话用于所有10个请求?将不胜感激任何详细解释此概念的示例或链接.
解决方法:
JMS通过以下几个功能支持此功能:
首先,JMSCorrelationId是一个JMS头,用于将请求与响应相关联.即每个消息都包含一个全局唯一(GUUID)JMSMessageId.大型机应用程序应该简单地将消息ID从请求复制到响应消息上的JMSCorrelationId,然后发送回共享响应队列.
因此,只需通过以下方式发送请求:
(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.
允许多个使用者线程(或应用程序)的诀窍是使用者中的选择器. JMS选择器类似于SQL或类似查询语言的子集.在这种情况下,只需选择JMSCorrelationId与请求中的id相同的消息,就可以发送一些时间.
这是您可以对具有一个固定的共享队列的约束进行的唯一“安全”设置,并且请求必须返回到与它所请求的线程相同的线程.
为了避免JMS选择器的开销,您可以另外使用临时队列进行答复,每个请求一个临时队列,然后将没有其他线程在侦听特定的响应.获得性能的另一个选择是使应用程序更加异步. JMS实际上促进了这一点,触发了一个请求,并让使用者线程池处理任何异步响应-每个线程都具有处理任何响应的能力-就像处理数据并将其放入数据库(或类似数据库)一样.我不知道这种设计范例是否适用于您的情况,但是至少您应该意识到这一点.