JMS如何在内部工作?

Tra*_*vis 33 java messaging jms message-queue

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

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

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

在阅读有关技术时,让我烦恼的一件事就是当某个特征(有意或无意)挥手时.

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

问题2:如果没有消息可以接收(通常)阻止?

问题2b:如果是这样,阻塞是如何实现的?客户端是否不断轮询消息?在发布消息之前,服务器是否只是不响应(如何在没有超时的情况下工作?)提供者是否会向接收者发起呼叫?

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

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

问题3:JMS如何扩展?

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

问题3b:JMS实施如何确保在规模化环境中可靠交付?

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

ag1*_*112 19

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

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

怎么收到工作?JMS规范提供了两个重要的类: - MessageConsumer和MessageListener.MessageConsumerclass允许JMS客户端通过调用其任何receive()方法来同步接收JMS消息.在收到消息之前,此调用将阻塞线程.否则,可以通过注册MessageListenerwith 的对象来进行异步接收MessageConsumer.JMSProvider了解消息是否到达其本地目的地,其作用是将消息传递给轮询消息使用者线程或非轮询注册消息侦听器线程.

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

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

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

答案3: - 我想通过JMS扩展你的意思是拥有许多发布者/订阅者,多个物理机器上的许多目标.JMS扩展需要支持底层消息传递提供程序以支持某种类型的群集/故障转移.因此,JMS规范不支持可伸缩性.如果我错了,请纠正我?例如,我参与了符合JMS的WebSphere MQ,它提供了集群支持.


Ani*_*kur 5

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

让我们先把术语弄好.你不能说JMS Provider must be running因为provider是一个构建了JMS服务器的实体,它是必须运行的JMS服务器.因此,当我们说JMS时,我们指的是提供程序实现的一组API(技术上更为接口).所以基本上提供者编写自己的JMS实现.例如,Active MQ is a JMS server那是由提供的Apache(provider)

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

真的在一定程度上.遵循不同的模型.JMS服务器保持套接字打开.每当发送方客户端必须发送消息时,它只需打开与套接字的连接并发送消息.接收行为如何完全不同.你有拉动和推动.在推送服务器中,一旦收到消息,就会将消息推送到实时接收器客户端.这也称为异步模式.在拉模型中,客户端接收器向服务器发送请求以获取消息(同步模式).

如果没有消息可以接收(通常)阻止?

正如我在前面提到的那样,它将取决于您使用的模型.接收器将在拉模型中被阻止(同步接收).这也发生在Session线程中,而不是主线程.

如果是这样,阻塞是如何实现的?客户端是否不断轮询消息?

是的,客户将在拉模型的情况下不断进行投票.通常会有超时,客户端将被终止.

如果没有,如何在不影响性能的情况下及时确保收到消息?

使用异步模式.您只需注册一个MessageListener,当服务器上有消息可用时,它将在其上接收消息onMessage(Message msg).

问题3:JMS如何扩展?

对于提供商而言,这确实是一个令人担忧的问题.当您说所有订户都收到消息时,您指的是PUBSUB通信模型(其他是PTP).在PUBSUB中,发送给主题的消息将被传递给订阅该主题的所有订阅者.

问题3b:JMS实施如何确保在规模化环境中可靠交付?

可靠性?不总是.同样,这取决于用例.您可以拥有持久性和非持久性消息.在持久消息的情况下,消息存储在DB(文件或其他)中,并确保它的传递.在非持久性消息的情况下,没有这样的保证.服务器故障可能导致邮件丢失.

  • 我仍在寻找更多细节 - 例如,考虑您的客户端位于一台服务器上,您的 JMS 提供程序是一个可扩展的系统(即,多个服务器)。从网络角度来看,客户端连接到什么,如何在相反方向传递响应。我认为您想说的是服务器发起回客户端的连接以传递消息。如果客户端离线怎么办?同样,我担心可靠性(保证交付、持久消息)和性能(交付时间)。 (2认同)