Java EE容器中的同步请求-应答模式



我希望在Java EE容器中使用JMS实现一个同步请求-应答模式。序列应该类似于这个

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

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

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

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

这取决于对"valid"的感知:它可能会编译并工作。但从设计的角度来看,可以说你真的可以改进它


如果您的线程被阻塞,任何异步通信都不会增加任何值。相反,它会使速度变慢,消耗资源,甚至可能制造麻烦(请参阅下面的链接)。

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

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

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

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


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

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

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

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

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

最新更新