Java 如何理解 JMS 中的“同步”和“异步”消息传递?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22088873/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to understand the "synchronous" and "asynchronouns" messaging in JMS?
提问by Freewind
After reading some document of JMS, I totally puzzled by the phrase synchronous
and asynchronouns
.
在阅读了 JMS 的一些文档后,我对这句话synchronous
和asynchronouns
.
See this page: http://docs.oracle.com/cd/E19798-01/821-1841/bncdq/index.html
请参阅此页面:http: //docs.oracle.com/cd/E19798-01/821-1841/bncdq/index.html
Synchronous
同步
You use the receive method to consume a message synchronously. You can use this method at any time after you call the start method:
connection.start(); Message m = consumer.receive(); connection.start(); Message m = consumer.receive(1000); // time out after a second
To consume a message asynchronously, you use a message listener, described in the next section.
您可以使用接收方法同步使用消息。您可以在调用 start 方法后随时使用此方法:
connection.start(); Message m = consumer.receive(); connection.start(); Message m = consumer.receive(1000); // time out after a second
要异步使用消息,请使用消息侦听器,将在下一节中介绍。
Asynchronous
异步
JMS Message Listeners A message listener is an object that acts as an asynchronous event handler for messages. This object implements the MessageListener interface, which contains one method, onMessage. In the onMessage method, you define the actions to be taken when a message arrives.
You register the message listener with a specific MessageConsumer by using the setMessageListener method. For example, if you define a class named Listener that implements the MessageListener interface, you can register the message listener as follows:
Listener myListener = new Listener(); consumer.setMessageListener(myListener);
JMS 消息侦听器 消息侦听器是充当消息的异步事件处理程序的对象。该对象实现了 MessageListener 接口,该接口包含一个方法 onMessage。在 onMessage 方法中,您定义消息到达时要采取的操作。
您可以使用 setMessageListener 方法向特定的 MessageConsumer 注册消息侦听器。例如,如果您定义了一个名为 Listener 的类来实现 MessageListener 接口,则可以按如下方式注册消息侦听器:
Listener myListener = new Listener(); consumer.setMessageListener(myListener);
I have two questions:
我有两个问题:
As what I understood, the nature of JMS is asynchronous. Producer publishes messages to the queue/topic, it doesn't need to wait consumer. This is asynchronous behaviour. How can it be "synchronous"?
If the "mesageListener" is asynchronous, but in my test with spring-jms, I found it always running in a thread. That means, if I write
Thread.sleep(2000)
inonMessage
, it have to be wait 2 seconds before processing next message. Is it "asynchronous"?
据我了解,JMS 的本质是异步的。生产者向队列/主题发布消息,不需要等待消费者。这是异步行为。怎么可能是“同步”的?
如果“mesageListener”是异步的,但在我使用 spring-jms 的测试中,我发现它总是在一个线程中运行。这意味着,如果我写
Thread.sleep(2000)
在onMessage
,它必须等待下一个处理消息之前2秒。它是“异步的”吗?
采纳答案by JB Nizet
If you understand it better like this, consumer.receive()
uses a pullmodel: you read from a queue and are blocked waiting for this message until it comes, or some timeout has elapsed.
如果您像这样理解它,请consumer.receive()
使用拉模型:您从队列中读取并被阻止等待此消息,直到它出现,或者一些超时已经过去。
Using a listener uses a pushmodel: you register a listener and, when a message comes in, the listener is called, in a separate thread.
使用侦听器使用推送模型:您注册一个侦听器,当消息传入时,在单独的线程中调用该侦听器。
Everything is done in a thread in Java, and the listener call is no exception. Whether the listener message handling prevents the processing of other messages in the queue depends on how many threads are dedicated to message processing. If you configure Spring to use a pool of 5 threads to process messages asynchronously, then 5 listeners will be able to process messages in parallel.
Java中一切都是在一个线程中完成的,监听器调用也不例外。侦听器消息处理是否阻止处理队列中的其他消息取决于有多少线程专用于消息处理。如果将 Spring 配置为使用 5 个线程池异步处理消息,则 5 个侦听器将能够并行处理消息。
回答by Dimitri Dewaele
Like I understand this:
像我这样理解:
asynchronous - MessageListener:Use this on a server that listens to a queue. When a message arrives, then deal with it immediately. The server keeps listening to this queue.
异步 - MessageListener:在侦听队列的服务器上使用它。当消息到达时,立即处理它。服务器一直在监听这个队列。
synchronous - consumer.receive(1000):Use this on a client applications that now and then needs to check if a message is intend for this client. Example: poll every 60 seconds. This only opens a connection to the server shortly. The 1000 milliseconds will keep this connection open. If a message arrives within these 1000 milliseconds, then the message is consumed and the connection is closed.
同步 - consumer.receive(1000):在客户端应用程序上使用它,该应用程序不时需要检查消息是否打算发送给该客户端。示例:每 60 秒轮询一次。这只会很快打开与服务器的连接。1000 毫秒将保持此连接打开。如果消息在这 1000 毫秒内到达,则消息将被消耗并关闭连接。
回答by Ramesh Natarajan
You are looking at it end-to-end: from publisher to the consumer. Yes, it is asynchronous delivery from publisher to consumer irrespective of Sync/Async consumer. However Sync/Async in your question is for consumer only, i.e from the JMS broker (eg: ApacheMQ) to the consumer. As others have pointed out, Sync consumers pull messages sequentially from the broker and are waiting for messages. Async consumers register a callback where messages pushed to them (onMessage). Async consumers can go about doing other things while these messages are delivered to them asynchronously from the JMS broker.
您正在端到端地查看它:从发布者到消费者。是的,无论同步/异步消费者如何,它都是从发布者到消费者的异步交付。但是,您问题中的同步/异步仅适用于消费者,即从 JMS 代理(例如:ApacheMQ)到消费者。正如其他人指出的那样,同步消费者从代理顺序拉取消息并等待消息。异步消费者注册一个回调,消息推送给他们 (onMessage)。当这些消息从 JMS 代理异步传递给异步消费者时,异步消费者可以做其他事情。
回答by Nagaraju Koppu
I understand synchronous/asynchronous differently.
我对同步/异步的理解不同。
Synchronous: Caller(Sender) has to wait till the response from consumer has been received(till the time-out) -- request/reply pattern
同步:调用者(发件人)必须等到收到消费者的响应(直到超时)——请求/回复模式
Asynchronous: Caller(Sender) just post message and continue with its work, while the consumer processes as soon as the message reaches it -- one way request
异步:Caller(Sender) 只是发布消息并继续其工作,而消费者在消息到达时立即处理——单向请求
Any MOM(Message Oriented Middle ware)follows service activator pattern which promotes asynchronous communication. One of my project has implemented a framework around JMS to make communication really synchronous.
任何MOM(面向消息的中间件)都遵循促进异步通信的服务激活器模式。我的一个项目已经实现了一个围绕 JMS 的框架,以使通信真正同步。
- Any message has 2 parts. a. Metadata attributes b. Payload
- Set attribute "reply-to-queue" to a randomly generated value
- Make sure the MOM framework creates temporary queue with name from #2
- Make sure the sender spawns thread, which listens to temporary queue created in #3
- Publish message and block sender till it receives message to temporary queue
- Make sure the consumer intercepts "reply-to-queue" header and publishes response to it
- 任何消息都有两部分。一种。元数据属性 B. 有效载荷
- 将属性“reply-to-queue”设置为随机生成的值
- 确保 MOM 框架使用 #2 中的名称创建临时队列
- 确保发件人产生线程,该线程侦听 #3 中创建的临时队列
- 发布消息并阻止发件人,直到它收到消息到临时队列
- 确保消费者拦截“reply-to-queue”标头并发布对它的响应
This is one of the ways to make MOM based communication acts like synchronous. You may find other implementations like request-reply mechanism.
这是使基于 MOM 的通信表现得像同步的方法之一。您可能会发现其他实现,例如request-reply 机制。