使用基于Pull的方式检索消息时,两个使用者能否获得同一组消息?

时间:2018-07-22 05:37:16

标签: java rabbitmq messaging

所以我有一个基于客户端-服务器的生态系统,我在其中使用RabbitMQ作为持久性中间件。

现在,一条消息的流是这样的。

  • 步骤1:客户端A将消息发送到带有目标的服务器 在该消息的元数据中设置为客户端B。
  • 第2步:服务器在收到消息后将消息推送到 RabbitMQ并向客户端B发送一条通知,告知他有一些消息 来获取。
  • 步骤3:收到通知后,客户端B调用提取消息API来 从服务器获取消息。
  • 第4步:在服务器上,从客户端B调用后拉 RabbitMQ使用基于拉的方法发送消息 (channel.basicGet(queueName, false))并移交给 消息。

现在在上面的流程中,我很少有疑问。

首先,如果我的客户端收到两个通知并两次调用请求消息API,则可能存在并发问题。

假设我在获取消息时没有发送消息确认,但随后又发送了,那么是否可以将同一条消息发送到两个请求API?如果是这样,有什么办法可以防止这种情况的发生?

从MQ获取消息的示例代码:

    long currentMessageCount = channel.messageCount(QUEUE_NAME);
    while (currentMessageCount-- > 0) {
        GetResponse getResponse = channel.basicGet(QUEUE_NAME, false);
        if (getResponse == null) {
            break;
        }
        AMQP.BasicProperties props        = getResponse.getProps();
        Envelope             envelope     = getResponse.getEnvelope();
        int                  messageCount = getResponse.getMessageCount();
        byte[]               body         = getResponse.getBody();
        /*
            Do some logic
         */
        channel.basicAck(envelope.getDeliveryTag(), false);
    }

TIA

1 个答案:

答案 0 :(得分:0)

basicGet很少是正确的解决方案。在步骤2中,客户端应该从RabbitMQ中使用。无需通知消息已准备就绪。 RabbitMQ将消息放入队列中后立即发送给客户端B。步骤3和步骤4变得不必要。


注意: RabbitMQ团队监视the rabbitmq-users mailing list,并且有时仅在StackOverflow上回答问题。