2013-08-31 87 views
3

我期待在Java EE容器内使用JMS实现同步请求 - 答复模式。序列会是这样的Java EE容器中的同步请求 - 答复模式

  1. 浏览器向Web应用程序请求数据。这是一个阻塞请求(在线程T1上说)。
  2. Web应用程序需要连接到远程Web服务才能满足上述请求。所以它形成一个请求并将它放在一个队列中(同时还声明了一个回复队列)。
  3. 远程服务处理请求并将响应放置到步骤2中声明的回复队列中
  4. 响应从Web应用中的回复Q中读取,并提供给阻塞线程T1第1步:

我都接着T.Rob所提供的答案(How to match MQ Server reply messages to the correct request

QueueReceiver queueReceiver = 
    session.createReceiver(destination, "JMSCorrelationID='customMessageId'"); 
TextMessage receivedMessage = (TextMessage)queueReceiver.receive(15000); 

在Java EE容器(Web模块)运行时,其中可能有多个是上述方案有效并发请求进入?

+0

是如何实现的远程服务:一个独立的队列接收器,MDB,另一个系统,...? – Beryllium

+0

远程服务作为MDB实现,它在预定义的队列上侦听请求。 – Rocky

回答

2

这取决于对“有效”的认识:它可能会编译和工作。但从设计的角度来看,可以说你可以真正改善它。


如果你的线程是阻塞,任何异步通信不会增加任何价值。相反,它会使它变慢,会消耗资源,甚至会造成麻烦(请参阅下面的链接)。

无论系统处理消息(可能是MDB)所暴露的任何服务,都将其提取到单独的服务类中,并以无状态会话bean的形式提供另一个前端。因此,您的服务可通过同步和异步界面进行公开,客户可以选择。

在你的场景中,你的servlet只是同步地调用一个EJB。

至于可能发生的其他问题:看看JMS request/response pattern in transactional environment(这种方法使用临时队列)。

使用单个队列(您在问题中引用的方式),需要一个选择器(条件)才能获取相关消息:此可能速度较慢,具体取决于队列中的卷。


在另一方面,如果你实现你的servlet 与异步支持以及(使用@WebServlet(asyncSupported = true)),这是不同的东西。在那种情况下,我会说这是一个有效的方法。

在这种情况下,您可以节省资源(即线程;但HTTP连接保持打开状态),因为一个后台线程监听队列可以服务多个客户端。如果您遇到性能问题或资源问题,请考虑这一点。在此之前,我建议采取同步方式,因为它更容易实施。