如何配置一个 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
队列的任何消息。队列名称在代理中是普遍唯一的。
我有一个没有预配置队列的嵌入式 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
队列的任何消息。队列名称在代理中是普遍唯一的。