使用消息ttl实现计划消息RabbitMQ时消息被卡住

时间:2018-06-22 06:37:07

标签: rabbitmq schedule

我需要安排延迟消息,所以我用x-dead-letter-exchange和x-dead-letter-routing-key声明一个延迟队列DELAY_STAT,它将路由到默认交换到我的目标队列STAT。

当我需要安排一个延迟消息到STAT队列时,我将该消息发布到DELAY_STAT中,并且到期时,到达消息ttl时,它将是一个死信,然后将其路由到STAT,以便可以使用它。

但是根据https://www.rabbitmq.com/ttl.html#per-message-ttl-caveats

,我遇到了问题
  

设置每条消息TTL时,过期消息可以在后面排队   未过期的,直到后者耗尽或过期

这意味着如果较早发送B,则一些短延迟消息A将被长延迟消息B阻塞。

1 个答案:

答案 0 :(得分:0)

如果您要安排要发送的邮件,可以 请执行以下操作。

  1. 将消息发布到队列时,必须计算消息的TTL。
  2. 在RabbitMQ中,您必须将消息发布到特定时间窗口的队列中。
  3. 当TTL到期时,该消息将消失,使用x-dead-letter-exchange的消息将转移到将要使用的目标队列中。

例如

让我们假设您的时间窗口为60秒,因此您将有一个单独的队列,用于接收TTL在0到59秒(含)之间的消息,其名称为queue.dlx.0,一个单独的队列,队列中的TTL在60到119秒之间,名称为queue.dlx.0,依此类推。

您知道对于当前消息TTL等于50秒。然后,您可以定义延迟队列名称queue.dlx + Math.floor(50/60)

当消息TTL过期时,消息死亡,并进入队列,在那里您有使用者来处理消息。

此外,您可以为每条消息创建一个队列,并设置队列TTL(x-expires)以在消息TTL过期(消息TTL +几秒钟以防万一)后删除该队列。

查看此图片: https://hsto.org/getpro/habr/post_images/1a2/95d/14f/1a295d14fbeea180e17636a86e8fbce6.png

(来源-https://habr.com/post/235983/ [RUS])

此外,您可以看看此插件https://github.com/rabbitmq/rabbitmq-delayed-message-exchange

Math.floor-JS函数将小数四舍五入为最小整数。