首页 文章

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

提问于
浏览
4

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

RabbitMQ会在消费者到达时向他们发送消息吗?
要么
RabbitMQ是否会在消费者可用时向其发送消息?

  • 在消息使用 endpoints ,我正在使用 com.rabbitmq.client.QueueingConsumer .

  • 看看sprint客户端源代码,我可以搞清楚

  • QueueingConsumer 继续侦听代理发送给它的任何消息的套接字

  • 收到的任何消息都会被解析并存储为 Delivery ,并封装在QueueingConsumer中的 LinkedBlockingQueue 中 .

  • 这意味着即使消息处理 endpoints 忙,消息也会被推送到QueueingConsumer

这种理解对吗?

2 回答

  • 2

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

    Details: 低级别(I 'm probably going to get some of this wrong) RabbitMQ itself doesn' t实际上推送消息 . 客户端必须根据AMQP协议不断读取帧的连接 . 很难将其分类为推或拉,但只知道客户端必须不断读取连接和因为Java客户端很遗憾BIO它是一个阻塞/轮询操作 . 阻塞/轮询基于AMQP心跳帧和常规帧和套接字超时配置 .

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

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

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

  • 5

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

相关问题