如何配置一个 ActiveMQ Artemis 队列不再被创建

How to configure an ActiveMQ Artemis queue not be created again

我有一个没有预配置队列的嵌入式 ActiveMQ Artemis 2.17.0 代理。我希望客户端连接到代理并在不存在时自动创建其队列。当我第一次 运行 客户端时,这工作得很好,但第二次我再次连接到代理时,客户端抛出错误:

errorType=QUEUE_EXISTS message=AMQ229019: Queue hornetq already exists on address router

是否可以配置客户端或服务器,使其在队列已经存在时不再尝试重新创建?

以下是我运行ning的程序:

服务器

try {
    ActiveMQServer server = new ActiveMQServerImpl(new ConfigurationImpl()
         .setPersistenceEnabled(true)
         .setBindingsDirectory("./router/data/bindings")
         .setLargeMessagesDirectory("./router/data/large")
         .setPagingDirectory("./router/data/paging")
         .setJournalDirectory("./router/data/journal")
         .setSecurityEnabled(false)
         .addAcceptorConfiguration("tcp", "tcp://0.0.0.0:61617?protocols=CORE,AMQP"));
    server.start();
} catch (Exception ex) {
    System.err.println(ex);
}

客户端

ServerLocator serverLocator = ActiveMQClient.createServerLocator("tcp://127.0.0.1.3:61617");
ClientSessionFactory factory = serverLocator.createSessionFactory();
ClientSession session = factory.createSession();
session.createQueue(new QueueConfiguration("router::hornetq")
        .setAutoCreateAddress(Boolean.FALSE)
        .setAutoCreated(Boolean.FALSE)
        .setRoutingType(RoutingType.ANYCAST));
ClientProducer producer = session.createProducer("router::hornetq");
ClientMessage message = session.createMessage(true);
message.getBodyBuffer().writeString("Core Queue Message");
producer.send(message);
session.start();
ClientConsumer consumer = session.createConsumer("router::hornetq");
ClientMessage msgReceived = consumer.receive();
System.out.println("message = " + msgReceived.getBodyBuffer().readString());
session.close();

我在这里使用完全限定的队列名称(即 router::hornetq),因为我在 router 地址上有多个队列。

您的客户端正在使用 核心 API,这是一个不支持自动队列创建的低级别 API。您的客户正在手动创建(或试图创建)队列,例如:

session.createQueue(new QueueConfiguration("router::hornetq")
        .setAutoCreateAddress(Boolean.FALSE)
        .setAutoCreated(Boolean.FALSE)
        .setRoutingType(RoutingType.ANYCAST));

如果队列已经存在,您看到的异常无疑会在此处抛出。创建队列不是幂等的,所以我可以看到 3 个选项:

  • 只需抓住这里抛出的 ActiveMQQueueExistsException 并忽略它。
  • 使用ClientSession.queueQuery 在尝试创建队列之前查看队列是否存在。如果它存在,则不要尝试再次创建它。如果它不存在,则创建它。也就是说,如果您同时有很多这样的客户端 运行,由于客户端之间的竞争条件,您仍然有可能获得 ActiveMQQueueExistsException
  • 使用支持自动创建的 client/protocol,例如核心 JMS 客户端或 AMQP。

还有几件事值得一提:

  • 因为你没有明确调用 ClientSession.createAddress() 你可能想使用 setAutoCreateAddress(Boolean.TRUE).
  • 您的消费者没有使用router::hornetq。它可以只使用 hornetq 并且它将接收发送到 hornetq 队列的任何消息。队列名称在代理中是普遍唯一的。