【问题标题】:How to redelivery messages that RabbitMQ already sent to consummers如何重新传递 RabbitMQ 已经发送给消费者的消息
【发布时间】:2018-04-05 13:53:12
【问题描述】:

我在 Rabbitmq 中创建了一些连接到队列的消费者,每次取消接收 X 条消息,例如 10,50,100 条,以避免不必要的连接一个一个地占用。 有时我们会遇到队列几乎是空的,只有一个消费者收到所有消息的情况。不幸的是,其中一条消息的处理速度可能很慢(例如,第三方 Web 服务超时),并且所有其他消息都必须排队等待这条消息完成,即使它们更快。 虽然这样,其他消费者是空的,无事可做,但他们无法接受第一个尚未处理的消息。

如果我可以告诉 Rabbitmq 向消费者传递某种消息,并且如果它在一段时间后没有确认,则必须将消息传递到队列并由另一个消费者接收。 有人知道是否有解决方法吗?

【问题讨论】:

    标签: rabbitmq queue timeout consumer subscriber


    【解决方案1】:

    Autoack 是假的,但我有很高的预取,比如 50 条消息,因为我想减少对 Rabbit 的调用。 目前我将预取更改为 5,因此当消息冻结时,消费者将只保留 5 条消息。我正在监控 Rabbit 服务器的性能,但我担心高峰时刻的消耗。 感谢 theMayer 的帮助。

    【讨论】:

    • 高预取与您发现的效果相同。请记住,超过 1 的预取在所有消息处理器中都是无意义的,但最快速的消息处理器除外(在这些处理器中,处理和传递所需的时间差不多)。
    【解决方案2】:

    看看我的answer to this question

    考虑以下场景:

    • 一个队列中有数千条消息
    • 单个消费者订阅队列时 AutoAck=true 且未设置预取计数

    会发生什么?

    RabbitMQ 的实现是传递任意数量的 向没有预取计数的客户端发送消息。此外,与 Auto-Ack,预取计数无关紧要,因为消息是 在交付给消费者时确认。

    因此,此时队列中的每条消息都将被传递到 消费者立即,消费者将被淹没 消息。假设每条消息很小,但需要 5 分钟 过程中,这个消费者完全有可能 在任何其他消费者附加到它之前耗尽整个队列。 并且由于 AutoAck 已打开,代理将忘记这些 发送后立即发送消息。

    如果您想获得这些,显然这不是一个好方案 处理的消息,因为它们已经离开了相对安全的 代理,现在位于消费端点的 RAM 中。比方说 遇到使消费端点崩溃的异常 - 噗,所有消息都不见了。

    我相信您所看到的是您将 AutoAck 设置为 true 的情况。发生这种情况时,如果在有机会连接之前没有其他消费者连接,第一个连接的消费者将耗尽整个队列。尝试将 AutoAck 设置为 false,然后选择合理的预取计数(可能是 0-1?),您将不会看到此行为继续。

    【讨论】:

      猜你喜欢
      • 2020-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-31
      • 2015-03-13
      • 1970-01-01
      • 2015-09-27
      相关资源
      最近更新 更多