如何解决如何配置一个 ActiveMQ Artemis 队列不再创建
我有一个没有预配置队列的嵌入式 ActiveMQ Artemis 2.17.0 代理。我希望客户端连接到代理并在它不存在时自动创建它的队列。这在我第一次运行客户端时工作得很好,但在第二次我再次连接到代理时,客户端抛出一个错误:
errorType=QUEUE_EXISTS message=AMQ229019: Queue hornetq already exists on address router
是否可以以这样的方式配置客户端或服务器,如果队列已经存在,则不应再次尝试重新创建它?
以下是我正在运行的程序:
服务器
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
。 - 使用支持自动创建的客户端/协议,如核心 JMS 客户端或 AMQP。
还有一些值得一提的事情:
- 由于您没有明确调用
ClientSession.createAddress()
,因此您可能想使用setAutoCreateAddress(Boolean.TRUE)
。 - 您的消费者不必使用
router::hornetq
。它可以只使用hornetq
并且它将接收发送到hornetq
队列的任何消息。队列名称在代理中普遍唯一。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。