我一直在研究各种通信技术/架构/模式/实现(阅读:流行语),包括 Web 服务(WCF、Axis2)、ESB、SOA,并想了解有关消息传递方面的 JMS 的更多信息。
从概念上讲,JMS 听起来很简单。我的看法是,它是一个中间代理,它管理来自发布者的消息并将它们路由到适当的订阅者。这是通过在消息发布时将消息排队并在收到消息时将其出列来完成的。
问题一:我对 JMS 的基本理解正确吗?
在阅读有关技术的文章时,让我感到困扰的一件事是,当某项功能发生某种程度的(有意或无意的)挥手时。
根据我的基本理解,必须运行 JMS 提供程序才能发送或接收消息。我对发布的假设是 JMS Provider 只是等待消息发布,然后将其存储在队列中(内存或数据库支持,取决于实现)。但是,我不太确定接收是如何工作的。
问题 2:如果没有可用的消息,接收(通常)会阻塞吗?
问题 2b:如果是,如何实现阻塞?客户端是否不断轮询消息?服务器是否只是在消息发布之前不响应(如何在不超时的情况下工作?)提供者是否向接收者发起调用?
问题 2c:如果不是,如何确保及时收到消息而不影响性能?
基本描述似乎倾向于单个 JMS 提供程序,以确保消息得到集中管理而不会丢失。我可以看到缩放是一个问题。
问题 3:JMS 如何扩展?
在扩展时,我可以看到确保将单个消息传递给所有适当订阅者的复杂性,无论哪个物理服务器接收消息。
问题 3b:JMS 实现如何确保在扩展环境中可靠交付?
请注意,尽管这些问题与 JMS 有关,但它们可能适用于任何消息传递基础架构。我欢迎针对 JMS 以及更通用甚至针对其他技术的答案。
最佳答案
我试图根据我在 JMS 上的经验回答几个问题。
答案1:- JMS 是Java Message Service API;它为 Java 客户端访问消息传递框架提供了统一的接口(interface)。在 JMS API 之下是一个与 JMS 兼容的消息传递提供程序,例如 WebSphere MQ 提供程序。 JMS 支持通过任何消息传递协议(protocol)将有效负载传输到目的地,即。队列和主题。 这些是 JMS 的基础知识。
接收是如何工作的?
JMS 规范提供了两个重要的类:- MessageConsumer
和 MessageListener
。 MessageConsumer
类允许 JMS 客户端通过调用其任何 receive()
方法来同步接收 JMS 消息。此调用将阻塞线程,直到收到消息。
否则,可以通过向 MessageConsumer
注册 MessageListener
的对象来进行异步接收。
JMSProvider 知道消息已到达其本地目的地,它的工作是将消息传递到轮询消息消费者线程或非轮询注册消息监听器线程。
答案 2:-
MessageConsumer
API 有两种接收变体:receive()
和 receive(long timeout)
。后一种变体让 MessageConsumer
线程阻塞,直到消息在特定超时期限内到达,否则超时。
不同的消息传递框架可能以不同的方式实现阻塞功能。由于 JMS 对象是 JNDI 管理的对象,并且提供者特定的代理对象返回给 JMS 客户端,这意味着客户端不知道阻塞是如何在后台发生的。特定的消息传递框架可能会在特定时间段后选择消息消费者线程轮询。或者,它可以选择阻止直到发送通知。
我不确定您是否正在寻找特定 JMS 兼容消息传递框架的答案?
答案 3:- 我想通过 JMS 扩展,您的意思是能够拥有许多发布者/订阅者,在多台物理机器上拥有许多目的地。 JMS 扩展需要支持底层消息传递提供程序以支持某种集群/故障转移。因此,JMS 规范不支持可伸缩性。如果我错了,请纠正我?例如,我曾在提供集群支持的 JMS 兼容 WebSphere MQ 上工作。
关于java - JMS Receive 如何在内部工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5952169/