我希望在 Java EE 容器内使用 JMS 实现同步请求-答复模式。顺序会是这样的
- 浏览器向 Web 应用程序发出数据请求。这是一个阻塞请求(比如在线程 T1 上)。
- Web 应用程序需要连接到远程 Web 服务才能满足上述请求。因此,它形成一个请求并将其放入队列中(还声明了回复队列)。
- 远程服务处理请求并将响应放入步骤 2 中声明的回复队列
- 该响应是从 Web 应用程序中的回复 Q 中读取的,并可供步骤 1 的阻塞线程 T1 使用。
我遵循了 T.Rob 提供的答案(如何将 MQ Server 回复消息与正确的请求相匹配 https://stackoverflow.com/questions/5021283/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 模块)中运行时,上述解决方案是否有效?
这取决于对“有效”的看法:它可能会编译并工作。但从设计的角度来看,可以说你确实可以改进它。
如果你的线程是blocking, any 异步沟通不会增加任何价值。相反,它会使速度变慢,会消耗资源,甚至可能会造成麻烦(请参阅下面的链接)。
无论处理消息的系统(可能是 MDB)公开什么服务,都将其提取到单独的服务类中,并以无状态会话 bean 的形式提供另一个前端。因此,您的服务通过同步和异步接口公开,客户端可以选择。
在您的场景中,您的 servlet 仅同步调用 EJB。
至于否则可能出现的问题:看看事务环境中的 JMS 请求/响应模式 https://stackoverflow.com/q/18464499/2390083(此方法使用临时队列)。
使用单个队列(您在问题中引用的方式),您需要一个选择器(条件)来获取相关消息:这might速度很慢,具体取决于队列中的数量。
另一方面,如果你实施你的具有异步支持的 servlet以及(使用@WebServlet(asyncSupported = true)
),这是不同的东西。在这种情况下,我会说这是一种有效的方法。
在这种情况下,您可以节省资源(即线程;但 HTTP 连接保持打开状态),因为一个后台线程监听队列可以为多个客户端提供服务。如果您遇到性能或资源问题,请考虑这一点。在此之前我建议使用同步方式,因为它更容易实现。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)