在队列声明错误时退出 Spring RabbitMQ 应用程序

问题描述

我的任务是创建一个简单的 Spring RabbitMQ 聊天应用程序。要求之一是只能有一个给定昵称的用户同时在线。用户通过他们的队列名称来区分。现在我在捕获队列声明错误时遇到了问题。在配置类中,我像这样声明了一个队列 bean

@Bean
public Queue privateQueue(String nickname) {
    String queueName = "prv." + nickname;
    return new Queue(queueName,false,true,true);
}

如果名称queueName 的队列已经存在,我想退出整个应用程序并打印出类似“用户名已被占用”的内容。这样做的最简单方法是什么?现在应用程序重试创建队列几次,然后由于 bean 创建失败而抛出 AmqpIOException 和其他。有没有办法捕获这些异常?

解决方法

按照设计,声明队列是一种幂等操作。因此,您可能没有收到错误消息,因为队列已经存在。

无论如何,您可以使用RabbitMQ HTTP API检查队列是否存在。

首先,如果这些依赖项不存在,则将它们添加到 pom.xml 中:

<dependency>
  <groupId>com.rabbitmq</groupId>
  <artifactId>http-client</artifactId>
  <version>3.10.0</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-web</artifactId>
  <version>5.3.6</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.12.3</version>
</dependency>

然后你可以这样做:

@Bean
@SneakyThrows
public Queue myQueue(String queueName) {
    Client client = new Client(new ClientParameters()
            .url("http://127.0.0.1:15672/api/").username("guest").password("guest"));

    QueueInfo queue = client.getQueue("/",queueName);

    if (queue == null) { // Does it exist?
        // Write to log,throw exception and etc'
        throw new RuntimeException("Queue " + queueName + " already exists!");
    }

    return new Queue(queueName,true);
}