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

时间:2012-08-16 05:50:24

标签: java jms message-queue

如果我使用以下代码创建发件人和收件人

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

然后执行此操作

qsender.send(msg);

它只是将消息发送到队列并且它将永远保留在队列中吗?我是否需要在接收器上调用receive()方法或实现MessageListener接口以将其传递给接收器?

修改:更多信息

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);

在上面的代码中,用于的临时队列是什么?它是否用于接收消息?是接收器吗?如果是,那么使用msg.setJMSReplyTo(temp1)是什么意思?

2 个答案:

答案 0 :(得分:2)

是的,send(..)方法会将消息发送到目标队列。此消息将保留在队列中,直到您的程序将使用接收器接收它或直到您的消息代理正在运行(据我所知)。

关于你的第二个问题,接下来是两种方法之间的区别:

接收(..)方法是同步的(这是这种方法的缺点)。这意味着接收方必须耐心等待消息到达,因为 receive ()消息将阻塞,直到消息可用(或直到发生超时条件)。从其他方面消费带有监听器的消息是异步过程。你的接收者不会等待。只有在将消息放入查询时,Listener才会调用您的接收方法。

<强>更新

临时目的地用于发送消费者对消息的回复。例如,可能是您的服务器从客户端收到消息并且您需要向他发送响应的情况。在这种情况下,您应该使用临时目的地。服务器应用程序将使用此临时目标(在您的情况下为队列)向客户端发送响应消息。此类队列的范围仅限于创建它的连接,并在连接关闭后立即在服务器端删除。

您可以在this articleofficila java tutorial中找到更多详细信息。在第二篇文章中还描述了如何以及何时使用JMSCorrelationID。

以下是来自官方文档的有趣部分,该文档描述了如何使用临时目标发送响应消息:

  

您可以使用临时目的地来实现简单的请求/回复   机制。如果您创建临时目标并将其指定为   发送消息时JMSReplyTo消息头字段的值,   然后消息的使用者可以使用JMSReplyTo的值   字段作为其发送回复的目标。消费者可以   还可以通过设置JMSCorrelationID来引用原始请求   回复消息的头字段为JMSMessageID的值   请求的标头字段。例如,onMessage方法可以   创建一个会话,以便它可以发送回复消息   收到。它可以使用如下代码:

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

更新2:

我想澄清一下我在队列(或主题)中的消息过期时间。默认情况下,邮件永不过期。但您可以设置消息的到期时间:

producer.setTimeToLive(60000);

在此之后,此MessageProducer生成的所有消息都将指定到期时间。

此外,您可以在发送时为具体消息指定到期时间:

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

其中10000表示10秒

答案 1 :(得分:2)

  1. 是的,它将始终保留在队列中,直到它被消耗或者手动或强制从队列中删除。这就是JMS的持久性属性,这就是它比RPC更受欢迎的原因。

  2. 关于receive方法,它是一个同步方法,在收到要消费的消息之前会阻塞该线程。

  3. 关于Message Listener实现,它遵循基于拉取的模型。消息代理在一段时间后继续查询JMS服务器,以查看是否有消息要消耗。

  4. 从选项3和选项4中选择取决于要求,阻止线程有其自身的缺点并且不会让任何事情变得更糟糕,并且轮询有其自身的缺点,特别是如果Jms服务器作为独立运行远程计算机上的服务器,并且代理必须在一段时间后使用RMI查询消息。

  5. UPDATE :: 如果你看一下企业集成请求/回复模式EIP,他们已经解释了因为消息传递使用异步过程,因此没有来自另一端。如果要向发件人发送有关邮件的确认,可以使用msg.setJMSReplyTo使用确认邮件Correlation id与发件人邮件ID匹配以同步请求响应。

    进入临时队列,它提供了在运行时创建队列,绑定到给定连接的好处,而不是在部署时静态定义队列,其优点是它提供了轻量级替代方案并有助于扩展系统在很大程度上。