如果消息被发布(确认已启用)到具有免费使用者的队列,RabbitMQ是否保证传递



上下文:

假设我使用RabbitMQ执行以下操作:

  1. 将使用者连接到RabbitMQ中的队列Q
    • 该消费者可以处于noack模式,也可以不处于;没有什么区别
    • 如果不处于noack模式;假设该消费者已经设置了CCD_ 4和CCD_;其缓冲区未满并且能够消耗
  2. 将发布服务器连接到同一RabbitMQ集群,并向Q发布强制消息(启用发布确认(
  3. 在发布服务器中接收basic.ack

问题:

  • 当返回basic.ack时,RabbitMQ是否保证已将该消息发送到消费者的远程套接字?我知道它不能保证消息已经到达消费者的本地套接字缓冲区,但我感兴趣的是代理是否发送了它
  • mandatory出版物的存在/不存在是否以任何方式影响这些保证
  • 在发布消息之前,队列是否完全为空,是否会以任何方式影响这些保证
  • RabbitMQ路由消息的版本是否以任何方式影响这些保证(即这些保证是否仅存在于某些RMQ版本中(
  • 消息的持久性是否会以任何方式影响这些保证
  • 目的地RMQ是否集群是否会以任何方式影响这些保证
  • 每条消息的过期时间是否以任何方式影响这些保证

TL;DR:RMQ是否在任何情况下向发布者保证已发布的消息已从代理发送给消费者

我尝试过的:

我尝试过通过连接消费者并将消息发布到不同配置的队列来测试这一点。消息通常在接收到basic.ack时已经被接收到。然而,我不能从中推断出任何保证,因为延迟和混乱在很多地方都会出现:

  • basic.ack返回发布者的传输时间
  • 消息正文到消费者的传输时间
  • 在发布者和使用者之间同步跟踪时钟(如果它们在不同的主机上/在不同的进程中(会使这一点难以证明

因此,由于内部代码流,我正在寻求代理本身提供的保证的知识,因为在外部验证这些东西(没有模糊器或类似jepsen的东西(。

RMQ是否在任何情况下向发布者保证已发布的消息已从代理发送给消费者?

没有。

发布者的ack是RabbitMQ交换机已接收到消息并将进行路由的声明。

例如,您可以使用未连接到队列的路由密钥将消息路由到遗忘状态。在这种情况下,发布者仍然会收到ack,因为消息已经发布。它只是没有去任何地方。