RabbitMQ:如果消费者永远消失,则删除队列?

问题描述 投票:0回答:3

想象每个用户都有自己的队列。当用户离线时,消息被放入队列中,当他们重新连接时,他们会收到所有这些消息。

但是,如果客户离开并且再也没有回来(停止使用服务)怎么办?如果消息一段时间没有被消费,RabbitMQ 是否有办法删除队列?消息可能会传入,但不会传出,因为客户端不再处于活动状态。我该如何使用 amqp.node 插件来处理这个问题?

javascript node.js rabbitmq amqp
3个回答
3
投票

想象每个用户都有自己的队列。当用户离线时,消息被放入队列中,当他们重新连接时,他们会收到所有这些消息。

这是一个常见的想法,但会带来不幸的后果,你应该避免

正如我在那篇链接文章中所写:

您可以通过为每个用户创建一个队列来解决这个问题。你 可以设置您的代码,以便网络服务器仅订阅 当用户登录并且可用时,为该用户排队。

这并不能解决问题。

现在您有 30,000 条消息分布在 1,000 个队列中 – 很糟糕 本身的情况。这需要 RabbitMQ 来持久化队列并 队列中的消息。当所有 1,000 个用户 同时登录您的系统?现在你的网络服务器有 1,000 队列订阅要处理。

当然,您可能会说您不会有那么多用户。但情况变得更糟。在您的情况下,您将无法按照您想要的方式自动删除队列。

您可以设置队列在所有消费者断开连接后自动删除。但是保持队列需要每个用户队列有一个消费者,只要该用户存在,消费者就保持连接。如果应用程序崩溃,队列及其所有消息都会消失。

TTL 只会做你想做的一部分。它会给队列中的消息赋予生命,并且该消息将在超时后被删除......但它不会删除队列。

最终,您不想使用 RabbitMQ 执行此操作。

再次来自我关于该主题的文章

回到最初的场景,当 用户不在线,您无法立即向他们发送消息?

将消息存储在数据库中。

在数据库记录中添加一个字段,表明该消息属于谁 到。当用户稍后重新连接时,查询数据库以查找任何 该用户当时需要查看并发送的消息。

完整的过程从上面开始,然后变成这样:

  • 用户浏览器连接到Web上的SignalR/Socket.io/Pusher/websockets 服务器
  • Web 服务器检查队列以查找长时间内发生的更新 运行过程
  • 当登录用户收到消息时
    • 如果 用户登录后,通过 websocket 广播消息到 用户
    • 如果用户未登录,则将消息存储在数据库中
  • 当用户再次登录时,查询数据库并发送所有等待 消息

这就是您在收到消息之前会做的事情 排队进来玩吧?这应该是你现在要做的 你也有一个消息队列。


0
投票

声明队列并将其独占属性设置为 True。这仅允许声明连接从队列中使用。当此连接关闭(并且所有消费者断开连接)时,队列将被自动删除。

https://www.rabbitmq.com/docs/queues#exclusive-queues


-2
投票

看起来是可以的,不过我自己没有尝试过。参见:

https://www.rabbitmq.com/ttl.html

查看底部的队列 TTL。 “这控制队列在自动删除之前可以不使用的时间。”

要查看示例用法,node-amqp 代码库中的此测试可能会很有启发:

https://github.com/postwait/node-amqp/blob/f64704d3727266230901598e2daf0fa780766feb/test/test-queue-args.js#L8

© www.soinside.com 2019 - 2024. All rights reserved.