通常在什么时候在消息代理中创建队列?例如,我的应用程序中有一个 RabbitMQ,因此我需要在启动它之前创建队列。
我仍在考虑类似于数据库迁移的方法,即创建需要在应用程序之前运行的脚本,但我还没有找到任何辅助工具。
在 RabbitMQ 中,通常的做法是在需要时在代码中创建队列。
我相信大多数客户端库都提供了幂等创建队列的可能性。例如,在创建队列消费者时,您可能会说“从这个队列中消费,如果不存在则创建它”。 这是 Java 中的示例:
Channel channel = connection.createChannel();
channel.queueDeclare("queue name", true, false, false, null); //here is the "create if does not exist" part
channel.queueBind("queue name", "exchange name", "routing");
根据我的经验,这是在 RabbitMQ 中管理队列的一种非常有效的方法。
出现的问题是您应该在何时何地创建此队列。这一切都取决于您的需求。基本上有三种方法:
如果您选择由消费者创建队列,则可以确保当有人需要从中消费时该队列就在那里。
缺点是,如果您在任何消费者存在之前向该队列生成消息(假设该队列是持久的),那么该消息将会丢失。这是否是一个问题取决于您的用例。
如果您选择在生产者和消费者端“创建如果不存在”队列,则可以确保消息永远不会丢失,即使该队列不存在消费者。 缺点是队列定义需要在生产者和消费者之间保持一致。例如,如果您在生产者中定义了一个具有相同名称但不同参数(例如持久性、参数等)的队列,则最终会出现异常,因为您无法定义具有相同名称但不同参数的队列。
这是我不推荐的选项,但同样,这取决于您的用例。在这种情况下,您需要确保在生成消息时不会丢失消息,但您需要确保生产者是在任何消费者存在之前创建的。否则,您将面临异常,因为消费者无法从不存在的队列中消费,也无法创建队列。
我尝试手动管理 RabbitMQ 队列,借鉴了我在 WLS 中使用 JMS 队列的经验,所以这是我的默认想法。然而,我发现这种方法极其繁琐、耗时,而且容易出错。