JMS 接收如何在内部工作?

2022-09-01 06:13:33

我一直在研究各种通信技术/架构/模式/实现(阅读:流行语),包括Web服务(WCF,Axis2),ESB,SOA,并希望了解有关JMS的更多信息。

从概念上讲,JMS听起来很简单。我的看法是,它是一个中间代理,它管理来自发布者的消息并将其路由到适当的订阅者。这是通过在发布消息时对消息进行排队,并在收到消息时对消息进行取消排队来完成的。

问题 1:我对 JMS 的基本理解是否正确?

在阅读有关技术的内容时,让我烦恼的一件事是,当对某个功能进行一定程度的(有意或无意的)挥手时。

根据我的基本理解,JMS 提供程序必须运行才能发送或接收消息。我对发布的假设是,JMS 提供程序只是等到消息发布,然后将其存储在队列中(内存或数据库支持,具体取决于实现)。但是,我不太确定接收是如何工作的。

问题 2:如果没有可用的消息,接收(通常)是否会阻塞?

问题2b:如果是这样,如何实现阻止?客户端是否持续轮询消息?服务器在发布消息之前是否根本没有响应(如何在不超时的情况下工作?提供程序是否启动对收件人的呼叫?

问题 2c:如果没有,如何确保及时接收消息,而不会影响性能?

基本描述似乎倾向于单个 JMS 提供程序,以确保消息得到集中管理而不会丢失。我可以看到缩放是一个问题。

问题 3:JMS 如何扩展?

在扩展时,我可以看到确保将单个消息传递给所有适当的订阅者的复杂性,而不管哪个物理服务器接收消息。

问题 3b:JMS 实现如何确保在扩展环境中可靠地交付?

请注意,尽管这些问题与 JMS 相关,但它们可能适用于任何消息传递基础结构。我欢迎特定于JMS的答案,以及那些更通用甚至特定于其他技术的答案。


答案 1

我试图根据我在JMS上的经验回答几个问题。

答案 1:-JMS是Java Message Service API;它为Java客户端访问消息传递框架提供了统一的接口。在 JMS API 之下是一个符合 JMS 的消息传递提供程序,例如 WebSphere MQ 提供程序。JMS 支持通过任何消息传递协议将有效负载传输到目标可视化项。队列和主题。这些是 JMS 的基础知识。

接收如何工作?JMS 规范提供了两个重要的类:- 和 . 类允许 JMS 客户机通过调用其任何方法来同步接收 JMS 消息。此调用将阻塞线程,直到收到消息。否则,可以通过注册 的对象与 进行异步接收。JMSProvider 知道消息已到达其本地目标,其工作是将消息传递到轮询消息使用者线程或非轮询注册消息侦听器线程。MessageConsumerMessageListenerMessageConsumerreceive()MessageListenerMessageConsumer

答案 2:- API 有两种接收变体:和 。后一种变体允许线程阻塞,直到消息在特定的超时期限内到达,否则它就会超时。MessageConsumerreceive()receive(long timeout)MessageConsumer

不同的消息传递框架可能以不同的方式实现阻止功能。由于 JMS 对象是 JNDI 管理的对象,而特定于提供程序的代理对象返回到 JMS 客户机,这意味着客户机不知道阻塞在后台是如何发生的。特定的消息传递框架可以在特定时间段之后选择消息使用者线程轮询。或者,它可以选择阻止,直到发送通知。

我不确定您是否正在寻找特定符合JMS的消息传递框架的答案?

答案 3:-我猜JMS扩展是指能够拥有许多发布者/订阅者,多个物理机器上的许多目的地。JMS 扩展需要支持底层消息传递提供程序来支持某种集群/故障转移。因此,JMS规范不支持可伸缩性。如果我错了,请纠正我?例如,我曾研究过与 JMS 兼容的 WebSphere MQ,它提供了集群支持。


答案 2

问题 1:我对 JMS 的基本理解是否正确?

让我们先把术语弄对。你不能说,因为提供者是构建了 JMS 服务器的实体,而 JMS 服务器必须运行。因此,当我们说JMS时,我们指的是提供商实现的一组API(更技术性 - 接口)。所以基本上提供者编写自己的JMS实现。例如,它由JMS Provider must be runningActive MQ is a JMS serverApache(provider)

我对发布的假设是,JMS 提供程序只是等到消息发布,然后将其存储在队列中(内存或数据库支持,具体取决于实现)。

在某种程度上是正确的。遵循不同的模型。JMS 服务器使套接字保持打开状态。每当发送方客户端必须发送消息时,它只需打开与套接字的连接并发送消息即可。接收的行为方式完全不同。你有。在推送服务器中,一旦收到消息,就会将消息推送到实时接收客户端。这也称为异步模式。在请求模型中,客户端接收器向服务器发送请求以获取消息(同步模式)。

如果没有可用的消息,接收(通常)是否会阻塞?

正如我在上一点中提到的,这将取决于您使用的模型。接收器将在拉模型中被阻止(同步接收)。此外,这发生在会话线程中,而不是主线程中。

如果是这样,如何实现阻止?客户端是否持续轮询消息?

是的,如果是拉模型,客户端将持续轮询。通常存在超时,在此之后客户端将被终止。

如果没有,如何确保及时接收消息,而不会影响性能?

使用异步模式。您只需要注册一个 MessageListener,当服务器上有消息可用时,它将在它被覆盖的消息接收消息。

问题 3:JMS 如何扩展?

这确实是提供商需要担心的问题。当您说所有订阅者都收到消息时,您指的是PUBSUB通信模型(其他是PTP)。在 PUBSUB 中,发送到主题的消息将传递给订阅该主题的所有订阅者。

问题 3b:JMS 实现如何确保在扩展环境中可靠地交付?

可靠性?并非总是如此。同样,这取决于用例。您可以有持久性和非持久性消息。对于持久性消息,消息存储在DB(文件或其他)中,并确保其传递。对于非持久性消息,则没有此类保证。服务器故障可能会导致邮件丢失。


推荐