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

时间:2014-06-19 14:35:49

标签: rabbitmq amqp

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

RabbitMQ是否会在消费者到达时向其发送消息?
OR
RabbitMQ是否会在消费者可用时向其发送消息?

  • 在消息使用端点,我正在使用com.rabbitmq.client.QueueingConsumer
  • 查看sprint客户端源代码,我可以搞清楚
    • QueueingConsumer继续侦听代理发送给它的任何消息的套接字
    • 将收到的任何消息解析并存储为Delivery,并封装在QueueingConsumer内部的LinkedBlockingQueue中。
  • 这意味着即使消息处理端点忙,消息也会被推送到QueueingConsumer

这种理解是对的吗?

3 个答案:

答案 0 :(得分:5)

TLDR:您从RabbitMQ轮询消息,直到超过预取计数为止,在这种情况下,您将阻止并仅接收心跳帧,直到获取消息为止。因此,您可以进行轮询,但如果非确认消息的数量小于预取计数,则只会获得新消息。新消息放在QueueingConsumer上,理论上你应该永远不会比QueueingConsumer内部队列中的预取计数多得多。

<强>详细信息: 对于(我可能会出现这种错误),RabbitMQ本身并没有实际推送消息。客户端必须根据AMQP协议不断读取帧的连接。很难将其归类为推或拉,但只知道客户端必须不断读取连接,因为Java客户端很遗憾BIO它是一个阻塞/轮询操作。阻塞/轮询基于AMQP心跳帧和常规帧和套接字超时配置。

Java RabbitMQ客户端中发生的事情是每个通道(或者可能是它的连接)都有线程,并且该线程从RabbitMQ循环收集帧,最终成为放入阻塞队列的命令(我相信它像SynchronousQueue又称切换队列,但兔子有自己特殊的一个)。

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

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

答案 1 :(得分:2)

我认为最佳答案是产品自己的答案。由于RMQ具有定义为协议一部分的推拉机制。看看:https://www.rabbitmq.com/tutorials/amqp-concepts.html

答案 2 :(得分:0)

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