简体   繁体   English

JMS如何在内部工作?

[英]How does JMS Receive work internally?

I've been researching various communication technologies/architectures/patterns/implementations (read: buzzwords) including Web Services (WCF, Axis2), ESBs, SOA, and wanted to know more about JMS with regards to messaging. 我一直在研究各种通信技术/体系结构/模式/实现(阅读:流行语),包括Web服务(WCF,Axis2),ESB,SOA,并希望了解有关消息传递的JMS。

Conceptually, JMS sounds simple. 从概念上讲,JMS听起来很简单。 My take is that it's an intermediate broker which manages messages from publishers and routes them to appropriate subscribers. 我的看法是它是一个中间代理,管理来自发布者的消息并将它们路由到适当的订阅者。 This is done by queueing messages as they are published, and dequeuing them as they are received. 这是通过在发布消息时对消息进行排队,并在收到消息时将它们出列来完成的。

Question 1: Is my basic understanding of JMS correct? 问题1:我对JMS的基本理解是否正确?

One of the things that bugs me when reading about technologies is when a certain level of (intentional or unintentional) hand-waving is done about a feature. 在阅读有关技术时,让我感到困惑的一件事就是当某个特征(有意或无意)挥手时。

Based on my basic understanding, a JMS Provider must be running in order to send or receive messages. 根据我的基本理解,必须运行JMS提供程序才能发送或接收消息。 My assumption on publishing is that the JMS Provider simply waits until a message is published, then stores it in a queue (memory or database-backed, depending on implementation). 我对发布的假设是JMS提供程序只是等待消息发布,然后将其存储在队列中(内存或数据库支持,具体取决于实现)。 However, I am not quite sure how receive works. 但是,我不太确定接收是如何工作的。

Question 2: Does receive (typically) block if no messages are avaiable? 问题2:如果没有消息可以接收(通常)阻止?

Question 2b: If so, how is blocking achieved? 问题2b:如果是这样,阻塞是如何实现的? Does the client continuously poll for messages? 客户端是否不断轮询消息? Does the server simply not respond until a message is published (how does this work without timing out?) Does the provider initiate a call to the recipient? 在发布消息之前,服务器是否只是不响应(如何在没有超时的情况下工作?)提供者是否会向接收者发起呼叫?

Question 2c: If not, how does one ensure messages are received in a timely manner, without impacting performance? 问题2c:如果没有,如何确保及时收到消息,而不影响性能?

The basic description seems to lean towards a single JMS provider to ensure that messages are centrally managed not lost. 基本描述似乎倾向于单个JMS提供程序,以确保集中管理消息而不会丢失。 I can see scaling being an issue. 我可以看到缩放是一个问题。

Question 3: How does JMS scale? 问题3:JMS如何扩展?

When scaling, I can see there being complexities to ensure that a single message is delivered to all appropriate subscribers, regardless of which physical server receives the message. 在扩展时,我可以看到存在复杂性以确保将单个消息传递给所有适当的订户,而不管哪个物理服务器接收到该消息。

Question 3b: How does a JMS implementation ensure reliable delivery in a scaled environment? 问题3b:JMS实施如何确保在规模化环境中可靠交付?

Please note that although these questions are related to JMS, they likely apply to any messaging infrastructure. 请注意,虽然这些问题与JMS有关,但它们可能适用于任何消息传递基础结构。 I welcome answers specific to JMS as well as those which are more general or even specific to another technology. 我欢迎特定于JMS的答案以及那些更通用或甚至特定于其他技术的答案。

I am trying to answer few questions based on my experience on JMS. 我试图根据我在JMS上的经验回答几个问题。

Answer 1:- JMS is Java Message Service API; 答案1: - JMS是Java Message Service API; it provides uniform interface for Java clients to access messaging framework. 它为Java客户端提供了访问消息传递框架的统一接口。 Beneath JMS API is a JMS compliant messaging provider, for example WebSphere MQ provider. JMS API下面是符合JMS的消息传递提供程序,例如WebSphere MQ提供程序。 JMS supports transport of a payload over any messaging protocol to destinations viz. JMS支持通过任何消息传递协议将有效负载传输到目标,即。 Queue and Topic. 队列和主题。 These are basics of JMS. 这些是JMS的基础知识。

How does receive work? 怎么收到工作? JMS specification provides two important classes:- MessageConsumer and MessageListener . JMS规范提供了两个重要的类: - MessageConsumerMessageListener MessageConsumer class allows a JMS client to synchronously receive JMS messages by calling any of its receive() method. MessageConsumer类允许JMS客户端通过调用其任何receive()方法来同步接收JMS消息。 This call will be blocking thread until a message is received. 在收到消息之前,此调用将阻塞线程。 Otherwise, asynchronous receive can be made by registering an object of MessageListener with MessageConsumer . 否则,可以通过向MessageConsumer注册MessageListener的对象来进行异步接收。 It is JMSProvider who get to know that a message is arrived in its local destination and its job is to deliver messages to either polling message consumer thread or non-polling registered message listener thread. JMSProvider了解消息是否到达其本地目的地,其作用是将消息传递给轮询消息使用者线程或非轮询注册消息侦听器线程。

Answer 2:- MessageConsumer API has two variants of receive: receive() and receive(long timeout) . 答案2: - MessageConsumer API有两种接收变体: receive()receive(long timeout) The latter variant lets MessageConsumer thread block until message arrives within specific timeout period or else it times out. 后一种变体允许MessageConsumer线程阻塞,直到消息在特定超时时间内到达,否则超时。

Different messaging frameworks might implement blocking feature in different ways. 不同的消息传递框架可能以不同的方式实现阻塞功能。 As JMS objects are JNDI administered objects and provider specific proxy objects are returned to JMS client, it means that the client is unaware of how blocking is happening in background. 由于JMS对象是JNDI受管对象,并且提供程序特定的代理对象被返回到JMS客户端,这意味着客户端不知道在后台发生阻塞的方式。 A particular messaging framework may choose message consumer thread polling after a particular time period. 特定消息传递框架可以在特定时间段之后选择消息消费者线程轮询。 Alternatively, it may choose to block until notification is sent. 或者,它可以选择阻止直到发送通知。

I am not sure if you are looking answer for a particular JMS compliant messaging framework? 我不确定您是否正在寻找特定的符合JMS的消息传递框架的答案?

Answer 3:- I guess by JMS scaling you mean ability to have many publishers/subscribers, many destinations over multiple physical machines. 答案3: -我想通过JMS扩展你的意思是拥有许多发布者/订阅者,多个物理机器上的许多目标。 JMS scaling requires support of underlying messaging provider to support some sort of clustering/fail over. JMS扩展需要支持底层消息传递提供程序以支持某种类型的群集/故障转移。 As such JMS specification does not support scalability. 因此,JMS规范不支持可伸缩性。 Correct me if I am wrong on this? 如果我错了,请纠正我? For example I have worked on JMS compliant WebSphere MQ which provides clustering support. 例如,我参与了符合JMS的WebSphere MQ,它提供了集群支持。

Question 1: Is my basic understanding of JMS correct? 问题1:我对JMS的基本理解是否正确?

Let's get the terminologies right first. 让我们先把术语弄好。 You cannot say JMS Provider must be running because provider is an entity that has built the JMS server and it is the JMS server that must be running. 您不能说JMS Provider must be running因为provider是构建JMS服务器的实体,它是必须运行的JMS服务器。 Hence, when we say JMS, we mean a set of APIs (more technically - interfaces) which providers implement. 因此,当我们说JMS时,我们指的是提供程序实现的一组API(技术上更为接口)。 So basically providers write their own JMS implementation. 所以基本上提供者编写自己的JMS实现。 For example, Active MQ is a JMS server that is provided by Apache(provider) 例如, Active MQ is a JMS serverApache(provider)提供Active MQ is a JMS server

My assumption on publishing is that the JMS Provider simply waits until a message is published, then stores it in a queue (memory or database-backed, depending on implementation). 我对发布的假设是JMS提供程序只是等待消息发布,然后将其存储在队列中(内存或数据库支持,具体取决于实现)。

True to some extent. 真的在一定程度上。 There are different models that are followed. 遵循不同的模型。 JMS server keeps a socket open. JMS服务器保持套接字打开。 Whenever a sender client has to send message it simply opens a connection to the socket and sends the message. 每当发送方客户端必须发送消息时,它只需打开与套接字的连接并发送消息。 How receive behaves is entirely different. 接收行为如何完全不同。 You have pull and push . 你有拉动推动 In push server will push the messages to the live receiver client as soon as it receives message. 在推送服务器中,一旦收到消息,就会将消息推送到实时接收器客户端。 This is also called asynchronous mode . 这也称为异步模式 In pull model client receiver sends request to server to get messages ( synchronous mode ). 在拉模型中,客户端接收器向服务器发送请求以获取消息( 同步模式 )。

Does receive (typically) block if no messages are avaiable? 如果没有消息可以接收(通常)阻止?

As I mentioned in previous point it will depend on the model you are using. 正如我在前面提到的那样,它将取决于您使用的模型。 Receiver will get blocked in pull model ( synchronous receive ). 接收器将在拉模型中被阻止( 同步接收 )。 Also this happens in Session thread , not the main thread. 这也发生在Session线程中 ,而不是主线程中。

If so, how is blocking achieved? 如果是这样,阻塞是如何实现的? Does the client continuously poll for messages? 客户端是否不断轮询消息?

Yes, client will continuously poll in case of pull model. 是的,客户将在拉模型的情况下不断进行投票。 Generally there is a timeout after which client will be terminated. 通常会有超时,客户端将被终止。

If not, how does one ensure messages are received in a timely manner, without impacting performance? 如果没有,如何在不影响性能的情况下及时确保收到消息?

Use asynchronous mode . 使用异步模式 You simply have to register a MessageListener and it will receive message on it's overridden onMessage(Message msg) when there is availability of messages on server. 您只需注册一个MessageListener ,当服务器上有消息可用时,它将在其上接收消息onMessage(Message msg)

Question 3: How does JMS scale? 问题3:JMS如何扩展?

It is really a question for providers to worry about. 对于提供商而言,这确实是一个令人担忧的问题。 When you say a message is received by all subscribers you are referring to PUBSUB model of communication (other being PTP ). 当您说所有订户都收到消息时,您指的是PUBSUB通信模型(其他为PTP )。 In PUBSUB message sent to a topic will be delivered to all the subscribers subscribed to that topic. 在PUBSUB中,发送给主题的消息将被传递给订阅该主题的所有订阅者。

Question 3b: How does a JMS implementation ensure reliable delivery in a scaled environment? 问题3b:JMS实施如何确保在规模化环境中可靠交付?

Reliability? 可靠性? Not always. 不总是。 Again, this depends on the use case. 同样,这取决于用例。 You can have persistent as well as non persistent Messages. 您可以拥有持久性非持久性消息。 In case of persistent messages, messages are stored in DB (file or others) and it's delivery is ensured. 在持久消息的情况下,消息存储在DB(文件或其他)中,并确保它的传递。 In case of non persistent messages there is no such guarantee. 在非持久性消息的情况下,没有这样的保证。 Server failure may result in message loss. 服务器故障可能导致邮件丢失。

I think the difference between Queue and Topic should be mentioned since there are important differences in the way messages are delivered. 我认为应该提到Queue和Topic之间的区别,因为消息的传递方式存在重大差异。

Queue: only one client will receive a message. 队列:只有一个客户端会收到一条消息。 To scale out, you can for example have 10 clients all connected to the same queue - but only one of them will receive a particular message. 例如,为了向外扩展,您可以将10个客户端连接到同一个队列 - 但只有其中一个客户端将收到特定的消息。 If no clients are connected, message will stay on the queue until someone connects or the message times out. 如果没有连接客户端,则消息将保留在队列中,直到有人连接或消息超时。

Topic: all clients will receive a copy of each message. 主题:所有客户都将收到每封邮件的副本。 Typically used in a subscriber scenario where many endpoints are potentially interested in each message. 通常在订户场景中使用,其中许多端点可能对每个消息感兴趣。 A durable subscriber can even be down for a while; 持久的用户甚至可能会停机一段时间; message will be kept until subscriber is up again or the message times out. 将保留消息,直到订户再次启动或消息超时。 If no clients are connected and there are no durable subscribers, message will be dropped. 如果没有连接客户端且没有持久订阅者,则将删除消息。

JMS support message consumption with a synchronous method (receive with and without timeout blocking your thread) or with a event driven callback (async message listener)). JMS支持使用同步方法消息(使用和不使用超时阻塞线程)或使用事件驱动的回调(异步消息侦听器))。

You can decide which method better fits your needs, but you also may need to have a look at the actual implementation. 您可以决定哪种方法更适合您的需求,但您也可能需要查看实际实现。 For example some JMS implementations do a network roundtrip for the receive() and therefore are better used with a timeout or with the listener. 例如,一些JMS实现为receive()执行网络往返,因此更好地使用超时或监听器。

With the message listener thread behaviour and pausing of message receipt are not so easyly controled as with a blocking receive call. 使用消息侦听器线程行为和暂停消息接收不像阻塞接收调用那样容易控制。 Typically most control is achieved by having your own pool of blocking receive() calls with timeouts, dispatching to your workers. 通常,大多数控制都是通过拥有自己的阻塞receive()调用池来实现的,这些调用具有超时,并分派给您的工作人员。

There are two types of messaging domains in JMS. JMS中有两种类型的消息传递域。

  1. P oint- T o- P oint( PTP ) Messaging Domain P oint-Ť邻- P oint(PTP)消息的域
  2. Publisher/Subscriber Messaging Domain 发布者/订阅者消息传递域

In PTP model , one message is delivered to one receiver only. 在PTP模型中 ,只有一条消息被传送到一个接收器。 Here, Queue is used as a M essage O riented M iddleware ( MOM ). 此处,队列被用作A M essageöriented 中号 iddleware(MOM)。

The Queue is responsible to hold the message until receiver is ready. 队列负责保留消息,直到接收器准备就绪。

In PTP model, there is no timing dependency between sender and receiver. 在PTP模型中,发送方和接收方之间没有时间依赖性。

在此输入图像描述


In Pub/Sub model , one message is delivered to all the subscribers. 在Pub / Sub模型中 ,一条消息被传递给所有订户。 It is like broadcasting. 这就像广播。 Here, Topic is used as a message oriented middleware that is responsible to hold and deliver messages. 这里,Topic用作面向消息的中间件,负责保存和传递消息。

In PTP model, there is timing dependency between publisher and subscriber. 在PTP模型中,发布者和订阅者之间存在时间依赖性。

在此输入图像描述


JMS Programming Model JMS编程模型

在此输入图像描述

source 资源


M essage D riven B ean (MDB) M essage D riven B ean(MDB)

  • MDB is a bean that contains business logic. MDB是一个包含业务逻辑的bean。 But, it is invoked by passing the message. 但是,通过传递消息来调用它。 So, it is like JMS Receiver. 所以,它就像JMS Receiver。
  • MDB asynchronously receives a message and processes it. MDB异步接收消息并对其进行处理。
  • MDB receives message from queue or topic. MDB从队列或主题接收消息。
  • MDB is like stateless session bean that encapsulates a business logic and does not maintain a state of the bean. MDB就像无状态会话bean,它封装了业务逻辑,并且不维护bean的状态。

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM