简体   繁体   English

发件人/收件人之间的JMS消息流

[英]JMS message flow between Sender/Receiver

If I use the following code to create a sender and receiver 如果我使用以下代码创建发件人和收件人

qsender = qsession.createSender((Queue)msg.getJMSDestination());
qreceiver=qsession.createReceiver((Queue)msg.getJMSDestination());

and then do this 然后这样做

qsender.send(msg);

Does it just send the message to the queue and will it remain in the queue forever? 它只是将消息发送到队列并且它将永远保留在队列中吗? Do I need to call the receive() method on the receiver or implement the MessageListener interface to get it to the receiver? 我是否需要在接收器上调用receive()方法或实现MessageListener接口以将其传递给接收器?

Edit: more info 编辑:更多信息

qsender = qsession.createSender((Queue)msg.getJMSDestination());
qreceiver=qsession.createReceiver((Queue)msg.getJMSDestination());

temp1 = qsession.createTemporaryQueue();
responseConsumer = qsession.createConsumer(temp1);
msg.setJMSReplyTo(temp1);

responseConsumer.setMessageListener(responseListener);
msg.setJMSCorrelationID(msg.getJMSCorrelationID()+i);

qsender.send(msg);

In the above code, what is the temporary queue used for? 在上面的代码中,用于的临时队列是什么? Is it for receiving the messages? 它是否用于接收消息? Is it the receiver? 是接收器吗? And if yes, whats the use of msg.setJMSReplyTo(temp1) ? 如果是,那么使用msg.setJMSReplyTo(temp1)什么?

Yes, send(..) method will send message to the destination queue. 是的,send(..)方法会将消息发送到目标队列。 And this message will remain in the queue until your program will receive it using receiver or until your message broker is running (as I know). 此消息将保留在队列中,直到您的程序将使用接收器接收它或直到您的消息代理正在运行(据我所知)。

About your second question then the difference between two approaches consist in next: 关于你的第二个问题,接下来是两种方法的区别:

receive (..) method is synchronous (and this is a downside of this approach). receive (..)方法是同步的(这是这种方法的缺点)。 This means that the receiver must wait patiently for the message to arrive, as the receive () message will block until a message is available (or until a timeout condition occurs). 这意味着接收方必须耐心等待消息到达,因为receive ()消息将阻塞,直到消息可用(或直到发生超时条件)。 From other side consuming messages with listener is asynchronous process. 从其他方面消费带有监听器的消息是异步过程。 Your receiver will not wait. 你的接收者不会等待。 Listener will call your receiving method only when message will be put to the query. 只有在将消息放入查询时,侦听器才会调用您的接收方法。

UPDATE: 更新:

Temporary destination is used for sending a reply on a message by consumer. 临时目的地用于由消费者发送消息的回复。 For example can be situation that your server get message from client and you need to send response to him. 例如,可能是您的服务器从客户端收到消息并且您需要向他发送响应的情况。 In such case you should use temporary destination. 在这种情况下,您应该使用临时目的地。 Server application will use this temporary destination (queue in your case) for sending a response message to client. 服务器应用程序将使用此临时目标(在您的情况下为队列)向客户端发送响应消息。 Such queues have a scope limited to the connection that created it, and are removed on the server side as soon as the connection is closed. 此类队列的范围仅限于创建它的连接,并在连接关闭后立即在服务器端删除。

More details you can find in this article and in officila java tutorial . 您可以在本文官方java教程中找到更多详细信息。 In second article also describes how and when to use JMSCorrelationID. 在第二篇文章中还介绍了如何以及何时使用JMSCorrelationID。

Here is interesting part from official doc that describes how to send response message using temporary destination: 这是官方文档中有趣的部分,它描述了如何使用临时目标发送响应消息:

You can use temporary destinations to implement a simple request/reply mechanism. 您可以使用临时目标来实现简单的请求/回复机制。 If you create a temporary destination and specify it as the value of the JMSReplyTo message header field when you send a message, then the consumer of the message can use the value of the JMSReplyTo field as the destination to which it sends a reply. 如果创建临时目标并在发送消息时将其指定为JMSReplyTo消息头字段的值,则消息的使用者可以使用JMSReplyTo字段的值作为其发送答复的目标。 The consumer can also reference the original request by setting the JMSCorrelationID header field of the reply message to the value of the JMSMessageID header field of the request. 消费者还可以通过将回复消息的JMSCorrelationID头字段设置为请求的JMSMessageID头字段的值来引用原始请求。 For example, an onMessage method can create a session so that it can send a reply to the message it receives. 例如,onMessage方法可以创建会话,以便它可以发送对它接收的消息的回复。 It can use code such as the following: 它可以使用如下代码:

producer = session.createProducer(msg.getJMSReplyTo());
replyMsg = session.createTextMessage("Consumer " +
    "processed message: " + msg.getText());
replyMsg.setJMSCorrelationID(msg.getJMSMessageID());
producer.send(replyMsg);

UPDATE 2: 更新2:

I want to clarify my unswer about message expiration time in the queue (or topic). 我想澄清一下我在队列(或主题)中的消息过期时间。 By default message will never expire. 默认情况下,邮件永不过期。 But you can set expiration time for message: 但您可以设置消息的到期时间:

producer.setTimeToLive(60000);

After this all messages produced by this MessageProducer will have specified expiration time. 在此之后,此MessageProducer生成的所有消息都将指定到期时间。

Also you can specify expiration tyme for concrete message during it's sending: 您还可以在发送时为具体消息指定到期时间:

producer.send(message, DeliveryMode.NON_PERSISTENT, 3, 10000);

where 10000 means 10 seconds 其中10000表示10秒

  1. Yes, it will always remain in the queue, until it is consumed or it is removed from the queue manually or forcefully. 是的,它将始终保留在队列中,直到它被消耗或者手动或强制从队列中删除。 And that's what about the durability property of JMS, and that's why it is preferred over RPC. 这就是JMS的持久性属性,这就是它比RPC更受欢迎的原因。

  2. About the receive method, it is a synchronous method and will block the thread until it receives a message to be consumed. 关于receive方法,它是一个同步方法,并将阻塞该线程,直到它收到要使用的消息。

  3. About the Message Listener implementation, it follows the pull based model. 关于Message Listener实现,它遵循基于拉取的模型。 Message broker keeps on querying the JMS server after some time, to see if there is a message to be consumed. 消息代理在一段时间后继续查询JMS服务器,以查看是否有消息要消耗。

  4. Choosing from Option 3 and Option 4 depends on the requirements, blocking the thread has its own downside and will not let anything go furhter, and polling has its own downside, specially if the Jms server is running as a standalone server on a remote machine, and the broker has to use RMI to query for messages after some time. 从选项3和选项4中选择取决于要求,阻塞线程有其自身的缺点并且不会让任何事情变得更糟糕,并且轮询有其自身的缺点,特别是如果Jms服务器作为远程机器上的独立服务器运行,并且代理必须在一段时间后使用RMI查询消息。

UPDATE :: If you look at the enterprise integration Request/Reply patterns EIP , they have explained that because the messaging uses an asynchronous process, and hence there is no acknowledgment from the other end. 更新::如果您查看企业集成请求/回复模式EIP ,他们已经解释了因为消息传递使用异步进程,因此没有来自另一端的确认。 If you want to send an acknowledgment back to the sender about the message, you can use msg.setJMSReplyTo which uses the acknowledgment message Correlation id to match with the sender message id to sync the request response. 如果要向发件人发送有关邮件的确认,可以使用msg.setJMSReplyTo ,它使用确认邮件Correlation id与发件人邮件ID匹配以同步请求响应。

Coming to temporary queue, it offers the benefit of creating the queues at runtime, bound to the given connection, rather than statically defining the queues at the deployment time, and the advantage is that it gives the lightweight alternative and helps in scaling the system to a much extent. 进入临时队列,它提供了在运行时创建队列,绑定到给定连接的好处,而不是在部署时静态定义队列,其优点是它提供了轻量级替代方案,并有助于将系统扩展到在很大程度上。

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

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