3

我希望在 Java EE 容器中使用 JMS 实现同步请求-回复模式。序列将是这样的

  1. 浏览器向 Web 应用程序发出数据请求。这是一个阻塞请求(比如在线程 T1 上)。
  2. Web 应用程序需要连接到远程 Web 服务才能完成上述请求。因此它形成一个请求并将其放置在一个队列中(还声明了一个回复队列)。
  3. 远程服务处理请求并将响应放入步骤 2 中声明的回复队列
  4. 响应从 web 应用程序中的回复 Q 中读取,并可供步骤 1 的阻塞线程 T1 使用。

我已按照 T.Rob 提供的答案(如何将 MQ 服务器回复消息与正确的请求相匹配

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

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

4

2 回答 2

2

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


如果您的线程处于阻塞状态,则任何异步通信都不会增加任何价值。相反,它会使它变慢,它会消耗资源,甚至可能会造成麻烦(见下面的链接)。

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

在您的场景中,您的 servlet 只是同步调用 EJB。

至于其他可能发生的问题:查看事务环境中的 JMS 请求/响应模式(这种方法使用临时队列)。

使用单个队列(您在问题中引用的方式),您需要一个选择器(条件)来获取相关消息:这可能会很慢,具体取决于队列中的数量。


另一方面,如果您也使用异步支持来实现您的 servlet(使用@WebServlet(asyncSupported = true)),那么情况就不同了。在那种情况下,我会说这是一种有效的方法。

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

于 2013-08-31T13:47:14.630 回答
0

EAI 模式的JMS 请求/回复可能适合您。

解释得很好,Java 中也有示例:

http://www.enterpriseintegrationpatterns.com/patterns/messaging/RequestReplyJmsExample.html

于 2016-02-17T12:14:50.270 回答