当消息可用时,JMS receiveNoWait() 是否保证消息传递?

Does JMS receiveNoWait() guarantee message delivery when messages are available?

你好,我正在编写一些简单的测试场景,我在其中执行以下源代码:

这是我的 send() 方法:

public void send() throws JMSException {

    Session session = null;
    MessageProducer producer = null;

    try {
        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

        Destination destination = session.createQueue("TEST.FOO");

        producer = session.createProducer(destination);
        producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);

        byte[] uselessData = new byte[1024];

        BytesMessage message = session.createBytesMessage();
        message.writeBytes(uselessData);

        producer.send(message);

    } finally {
        producer.close();
        session.close();
    }
}

这是我的 receive() 方法:

public void receive() throws JMSException {

    Session session = null;
    MessageConsumer consumer = null;

    try {
        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        Destination destination = session.createQueue("TEST.FOO");
        consumer = session.createConsumer(destination);

        Message hugeMessage = consumer.receiveNoWait();

        if (hugeMessage == null) {
            System.out.println("Message was not received");
            unsucsesfullCount++;
        } else {
            if (hugeMessage instanceof BytesMessage) {
                System.out.println("Message received");
            }
        }
    } finally {
        consumer.close();
        session.close();
    }

}

我执行:

send();
receive();

receiveNoWait()后的消息值总是null.

我的问题是,当代理中有消息时,receiveNoWait() 是否保证消息传递? send() 已成功执行,因此目标中至少有一条消息。

我已经在规范中进行了搜索,但是对于在代理端可用的消息是否应该由客户端的 receiveNoWait() 明确接收并没有真正明确的定义边.

另外我想问一下,如果receiveNoWait()没有消息可用,是不是应该在broker中触发一些刷新消费者进程,所以下一个 receiveNoWait() 会收到消息吗?

我在 ActiveMQ 上 运行 提供的示例代码,但我的问题更概念化而不是特定于提供者,因为我对其他 JMS 提供者有相同的观察。

不,规范不保证对 receiveNoWait 的任何调用都会 return 一条消息,可能会,也可能不会。使用 receiveNoWait 时,您必须始终检查空值 return 并采取相应措施。

在 ActiveMQ 的情况下,客户端将 return 一条消息,如果代理已向其发送一条消息,并且它立即在消费者预取缓冲区中可用,否则它只是 return 为空。

其他实现我确实向代理发送了一个轮询请求,例如 Qpid JMS 使用 AMQP link drain 请求来要求代理向它发送任何可用于调度的消息,并且代理将要么发送它们或发出 link 已耗尽并且没有消息准备就绪的信号。

简而言之,这完全取决于客户和经纪人如何实施 receiveNoWait,但无论什么,您始终需要考虑到您不会收到消息的可能性 returned你从那个方法。