为什么从队列消费时需要循环调用?

Why is the looping call required when consuming from queue?

我正在尝试使用 pika 和 twisted 从兔子队列中消费:

  1. 不断(新消息 -> 消费)
  2. 一次(新消息->消费一次,我说了再消费)

我唯一的输入是 example。它涵盖了用例 1。那么用例 2 呢?

basic_consume 的实现方式是否会在新消息准备就绪时 "notify"?为什么是我的"job"开始循环调用?轮询似乎是违反事件循环模式的,不是吗?

当使用 twisted 发出 http 请求时,它会发送请求并在返回后继续执行(通过延迟)。为什么这在 RabbitMQ/pika 中不起作用?

这是我希望它的工作方式:

  1. 订阅队列
  2. 从队列中消费(不会立即触发,除非队列中有消息,每次队列中有新消息时都会触发,我忽略了 qos 现在。)

如何使用单个消息,例如basic_get?我是否需要开始循环调用,一旦收到消息就停止?

RabbitMQ 团队监控 the rabbitmq-users mailing list 并且有时只在 Whosebug 上回答问题。


你问了几个问题,我会尽量一一回答。我是 Pika 的维护者之一,但不像其他连接适配器那样熟悉 Twisted。

Isn't basic_consume implemented in a way that it will "notify" when a new message is ready? Why is it my "job" to start the looping call? It seems that polling is against the event loop pattern in twisted, no?

Twisted's documentation for LoopingCall 指出:

Call a function repeatedly. If f returns a deferred, rescheduling will not take place until the deferred has fired.

example code 使用 @defer.inlineCallbacksyield 语句来 return 延迟函数。因此,LoopingCall 不会 重复调用该函数,它只会在 deferred 触发后安排新的调用。

Here is how I would expect it to work... consume from queue (doesn't fire immediately unless there is a message in the queue, will fire every time when there is a new message in the queue, I am ignoring qos for now.)

这正是示例代码的工作原理。

How do I consume a single message, e.g. basic_get? Do I need to start the looping call, and once I received the message, stop it?

如果您将预取 (QoS) 设置为 1,那么 RabbitMQ 只会向消费者发送一条消息,并且在第一条消息被 basic_ack 确认之前不会发送下一条消息。