RabbitMQ如何向消费者发送消息?

RabbitMQ如何向消费者发送消息?,rabbitmq,amqp,Rabbitmq,Amqp,我是RabbitMQ的新手,因此需要一个基本问题的指导: RabbitMQ是否在消息到达时向消费者发送消息? 或 RabbitMQ是否在消费者可用时向其发送消息 在消息消费端点,我使用的是com.rabbitmq.client.QueueingConsumer 看看sprint客户端的源代码,我就知道了 QueueingConsumer一直在套接字上侦听代理发送给它的任何消息 接收到的任何消息都将被解析并作为传递存储在封装在QueueingConsumer中的LinkedBlockingQu

我是RabbitMQ的新手,因此需要一个基本问题的指导:


RabbitMQ是否在消息到达时向消费者发送消息?


RabbitMQ是否在消费者可用时向其发送消息

  • 在消息消费端点,我使用的是
    com.rabbitmq.client.QueueingConsumer
  • 看看sprint客户端的源代码,我就知道了
    • QueueingConsumer
      一直在套接字上侦听代理发送给它的任何消息
    • 接收到的任何消息都将被解析并作为
      传递
      存储在封装在QueueingConsumer中的
      LinkedBlockingQueue
  • 这意味着,即使消息处理端点忙,消息也将被推送到QueueingConsumer

这种理解正确吗

TLDR:您轮询来自RabbitMQ的消息,直到超过预回迁计数,在这种情况下,您将阻止并仅接收心跳帧,直到回迁消息得到确认。因此,您可以进行轮询,但只有在未确认的邮件数小于预回迁计数时,您才会收到新邮件。新消息被放在QueueingConsumer上,从理论上讲,在该QueueingConsumer内部队列中,您的预回迁计数永远不会超过预回迁计数

详细信息: 低级明智的RabbitMQ本身实际上并不推送消息(我可能会有些误解)。客户端必须根据AMQP协议连续读取帧的连接。很难将其归类为推或拉,但只需知道客户机必须不断读取连接,而且由于Java客户机非常复杂,因此这是一个阻塞/轮询操作。阻塞/轮询基于AMQP心跳帧和常规帧以及套接字超时配置

Java RabbitMQ客户机中发生的情况是,每个通道(或其连接)都有线程,线程循环从RabbitMQ收集帧,这些帧最终成为放入阻塞队列的命令(我相信这类似于SynchronousQueue,也称为切换队列,但Rabbit有自己的特殊队列)

QueueingConsumer是一个更高级别的API,它将从前面提到的切换队列中提取命令,因为如果命令留在切换队列中,它将阻塞信道帧收集循环。这可能是错误的,因为连接超时。此外,QueueingConsumer允许在单独的线程上完成工作,而不是在与前面提到的循环帧线程相同的线程中


现在,如果您查看大多数消费者实现,您可能会注意到它们几乎总是无界阻塞队列。我不完全确定为什么这些队列的边界不能成为预取的乘数,但如果它们小于预取,肯定会导致连接超时问题。

我认为最好的答案是产品自己的答案。因为RMQ具有作为协议一部分定义的推拉机制。看看:

Rabbitmq主要使用推送机制。轮询将消耗服务器的带宽。轮询在每次轮询之间也有时间间隔。它将无法实现低延迟。一旦有消费者可用于队列,Rabbitmq就会将消息推送到客户端。因此,连接正在长时间运行。rabbitmq中的ReadFrame基本上是在等待传入帧

这更像是“拉队列还是推队列”问题?rabbitmq是否在消息到达时向消费者发送消息?或者RabbitMQ是否会在消息可用时向消费者发送消息?