Java EE 容器中的同步请求-回复模式
Posted
技术标签:
【中文标题】Java EE 容器中的同步请求-回复模式【英文标题】:Synchronous request-reply pattern in a Java EE container 【发布时间】:2013-09-03 19:56:21 【问题描述】:我希望在 Java EE 容器中使用 JMS 实现同步请求-回复模式。顺序应该是这样的
-
浏览器向 Web 应用程序发出数据请求。这是一个阻塞请求(比如在线程 T1 上)。
Web 应用程序需要连接到远程 Web 服务才能完成上述请求。因此它形成一个请求并将其放置在一个队列中(同时声明了一个回复队列)。
远程服务处理请求并将响应放入步骤 2 中声明的回复队列
从网络应用程序中的回复 Q 读取响应,并提供给步骤 1 的阻塞线程 T1。
我已关注 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 模块)中运行时,上述解决方案是否有效?
【问题讨论】:
远程服务是如何实现的:一个独立的队列接收器,一个MDB,另一个系统,...? 远程服务被实现为一个MDB,它在预定义的队列上监听请求。 【参考方案1】:EAI 模式的 JMS 请求/回复可能适合您。
解释得很好,Java 中也有示例:
http://www.enterpriseintegrationpatterns.com/patterns/messaging/RequestReplyJmsExample.html
【讨论】:
【参考方案2】:这取决于对“有效”的看法:它可能会编译并工作。但从设计的角度来看,可以说你真的可以改进它。
如果您的线程阻塞,任何异步通信都不会增加任何价值。相反,它会使其变慢,会消耗资源,甚至可能会造成麻烦(请参阅下面的链接)。
处理消息的系统(可能是 MDB)公开的任何服务,将其提取到单独的服务类中,并以无状态会话 bean 的形式提供另一个前端。因此,您的服务同时通过同步和异步接口公开,客户端可以选择。
在您的场景中,您的 servlet 只是同步调用 EJB。
至于其他可能出现的问题:看看JMS request/response pattern in transactional environment(这种方法使用临时队列)。
使用单个队列(您在问题中引用的方式),您需要一个选择器(条件)来获取相关消息:这可能会很慢,具体取决于队列中的数量.
另一方面,如果您也使用异步支持实现 servlet(使用@WebServlet(asyncSupported = true)
),情况就不同了。在那种情况下,我会说这是一种有效的方法。
在这种情况下,您可以节省资源(即线程;但 HTTP 连接保持打开状态),因为一个后台线程在队列上侦听可以为多个客户端提供服务。如果您有性能或资源问题,请考虑这一点。在那之前我建议使用同步方式,因为它更容易实现。
【讨论】:
以上是关于Java EE 容器中的同步请求-回复模式的主要内容,如果未能解决你的问题,请参考以下文章