【问题标题】:Why is the looping call required when consuming from queue?为什么从队列消费时需要循环调用?
【发布时间】:2023-12-19 22:43:01
【问题描述】:

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

  1. 不断(新消息 -> 消费)
  2. 一次(新消息 -> 消费一次,在我说之前不要再次消费)

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

basic_consume 不是以在新消息准备好时“通知”的方式实现的吗?为什么开始循环呼叫是我的“工作”?轮询似乎与扭曲的事件循环模式相反,不是吗?

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

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

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

我如何使用一条消息,例如basic_get?我是否需要启动循环调用,并在收到消息后停止它?

【问题讨论】:

    标签: rabbitmq twisted pika python-pika


    【解决方案1】:

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


    您问了几个问题,所以我会尽力回答所有问题。我是 Pika 的维护者之一,但对 Twisted 的了解不如其他连接适配器。

    basic_consume 不是以在新消息准备好时“通知”的方式实现的吗?为什么开始循环呼叫是我的“工作”?轮询似乎与扭曲的事件循环模式相反,不是吗?

    Twisted's documentation for LoopingCall 声明:

    重复调用一个函数。如果 f 返回一个 deferred,则在 deferred 被触发之前不会重新调度。

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

    这是我期望它的工作方式...从队列中消费(除非队列中有消息,否则不会立即触发,每次队列中有新消息时都会触发,我忽略了目前的 qos。)

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

    我如何使用一条消息,例如basic_get?我是否需要启动循环调用,并在收到消息后停止它?

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

    【讨论】: