【问题标题】:JmsTemplate with RECEIVE_TIMEOUT_NO_WAIT doesn't retrieve messages from JMS queue带有 RECEIVE_TIMEOUT_NO_WAIT 的 JmsTemplate 不会从 JMS 队列中检索消息
【发布时间】:2018-06-21 20:33:55
【问题描述】:

鉴于我有 ActiveMQ 队列,其中已经存在许多消息。

当我将JmsTemplate 上的接收超时设置为RECEIVE_TIMEOUT_NO_WAIT 等于-1

jmsTemplate.setReceiveTimeout(JmsTemplate.RECEIVE_TIMEOUT_NO_WAIT); 

并尝试接收其中一条消息:

Message msg = jmsTemplate.receive(queueName);

那么msg就是null,但是不应该按照JavaDoc:

/**
 * Timeout value indicating that a receive operation should
 * check if a message is immediately available without blocking.
 */
public static final long RECEIVE_TIMEOUT_NO_WAIT = -1;

这是为什么呢?

当我这样做时:

jmsTemplate.setReceiveTimeout(1000);

然后检索消息。

【问题讨论】:

  • 我怀疑随后的无等待调用将起作用(在第一个等待之后)。我刚刚查看了ActiveMQMessageConsumer.receiveNoWait() 方法,他发送了一个拉取请求,但是当然,该请求并没有立即得到满足,所以还没有消息。最终这些消息会到达,并且不等待选项应该会起作用。
  • 看起来很奇怪..将JmsTemplate从某个超时重新配置为RECEIVE_TIMEOUT_NO_WAIT有什么好处..我可以继续使用原始超时..我没有看到任何用例它:)

标签: spring jms spring-jms jmstemplate


【解决方案1】:

它与JmsTemplate 完全无关,因为它只是委托给底层JMS Consumer 对象:

protected Message receiveFromConsumer(MessageConsumer consumer, long timeout) throws JMSException {
    if (timeout > 0) {
        return consumer.receive(timeout);
    }
    else if (timeout < 0) {
        return consumer.receiveNoWait();
    }
    else {
        return consumer.receive();
    }
}

我会说它完全按照 JMS 设计者的意图工作:

/** Receives the next message if one is immediately available.
  *
  * @return the next message produced for this message consumer, or 
  * null if one is not available
  *  
  * @exception JMSException if the JMS provider fails to receive the next
  *                         message due to some internal error.
  */ 

Message receiveNoWait() throws JMSException;

换句话说,它适用于您绝对不想在任何时候阻塞线程的用例,如果当前没有消息已由代理发送给消费者 - 甚至等待网络 I/O 完成,这正是 ActiveMQ 实现它的方式 - 启动 I/O,但如果该 I/O 没有立即完成则返回 null(如果涉及网络,则很可能是这种情况) .

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-19
    • 2011-01-13
    • 1970-01-01
    • 1970-01-01
    • 2010-12-30
    相关资源
    最近更新 更多