3

我最近开始学习 JMS,到目前为止了解了一些概念。但是我想知道 IBM MQ 或任何队列提供程序如何处理来自多线程应用程序的请求。例如

考虑一个应用程序,它是多线程的并被配置为使用 MQ 向大型机主机发送消息。此应用程序配置了一个 Put 队列和 get 队列。想象一下正在处理 10 个请求,每个请求都想从主机获取数据。由于队列只是一个,所有这10条消息都同时放入队列中。主机处理消息并将回复发送给客户端,即应用程序。回复消息如何不会混淆并且每个线程都有自己的正确回复消息?

通信时使用了一些 id,它是否特定于发送的特定消息线程?是否需要为每个新的执行线程建立一个 JMS 会话。?所有 10 个请求都使用什么相同的会话?将感谢任何详细解释此概念的示例或链接。

4

1 回答 1

3

JMS 通过以下几个特性支持这一点:

首先,JMSCorrelationId 是一个 JMS 标头,用于将请求与响应关联起来。即每条消息都包含一个全局唯一的(GUID)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 实际上促进了这一点,触发一个请求,并让一个消费者线程池处理任何异步响应——每个线程同样能够处理任何响应——例如处理数据并将其放入数据库(或类似数据库)。我不知道这种设计范式是否适用于您的情况,但您至少应该知道这一点。

于 2012-08-13T14:16:17.873 回答