ipo*_*voy 2 java jms javalite activemq-artemis
我正在迁移JavaLite 异步从 Artemis 2.3.0 迁移到 2.11.0 版本。JavaLite Async 不使用任何文件基本配置,而是依赖于代码。
在 v 2.3.0 和 2.11.0 之间,JMS 管理 API 现已消失/已弃用,鼓励我们使用核心管理 API。
不幸的是我找不到办法:
这是一个示例(为了简洁起见,保留了导入):
class QueueLookup {
private static final String LOCATION = "./target/artemis";
private static EmbeddedActiveMQ server;
public static void main(String[] args) throws Exception {
try{
Configuration configuration = new ConfigurationImpl()
.setPersistenceEnabled(true)
.setBindingsDirectory(LOCATION + "/bindings")
.setJournalDirectory(LOCATION + "/journal")
.setLargeMessagesDirectory(LOCATION + "/largemessages")
.setPagingDirectory(LOCATION + "/paging")
.setSecurityEnabled(false)
.addAcceptorConfiguration("invm", "vm://0")
.setJournalBufferTimeout_AIO(100)
.setJournalBufferTimeout_NIO(100)
.setJournalType(JournalType.NIO)
.setMaxDiskUsage(90);
//the following three lines have no effect
CoreQueueConfiguration coreQueueConfiguration = new CoreQueueConfiguration();
coreQueueConfiguration.setName("Queue123").setDurable(true);
configuration.addQueueConfiguration(coreQueueConfiguration);
server = new EmbeddedActiveMQ();
server.setConfiguration(configuration);
server.start();
TransportConfiguration transportConfiguration = new TransportConfiguration(InVMConnectorFactory.class.getName());
ConnectionFactory connectionFactory = ActiveMQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF, transportConfiguration);
Hashtable<String, String> jndi = new Hashtable<>();
jndi.put("java.naming.factory.initial", "org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory");
jndi.put("connectionFactory.ConnectionFactory", "vm://0");
//# queue.[jndiName] = [physicalName]
jndi.put("queue.queue/Queue123", "Queue123");
InitialContext initialContext = new InitialContext(jndi);
Queue jmsQueue = (Queue) initialContext.lookup("queue/Queue123");
try (Connection connection = connectionFactory.createConnection()) {
try(Session jmsSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE)){
MessageProducer producer = jmsSession.createProducer(jmsQueue);
connection.start();
TextMessage message = jmsSession.createTextMessage("Hello, Artemis!");
producer.send(message);
System.out.println("Message sent: " + message.getText());
}
} catch (Exception ex){
ex.printStackTrace();
}
}finally {
server.stop();
}
}
}
Run Code Online (Sandbox Code Playgroud)
这些行没有任何作用:
CoreQueueConfiguration coreQueueConfiguration = new CoreQueueConfiguration();
coreQueueConfiguration.setName("Queue123").setDurable(true);
configuration.addQueueConfiguration(coreQueueConfiguration);
Run Code Online (Sandbox Code Playgroud)
但是,如果我删除这一行:
jndi.put("queue.queue/Queue123", "Queue123");
Run Code Online (Sandbox Code Playgroud)
那么 JNDI 找不到队列。
从表面上看,我似乎可以通过将队列名称添加到 JNDI 来“创建”队列:
jndi.put("queue.queue/Queue123", "Queue123");
Run Code Online (Sandbox Code Playgroud)
然而,这只能部分起作用,队列似乎存在来发送和接收消息,而既不存在也不QueueControl存在QueueBrtowser它。
有人可以解释一下我如何在代码中做到这一点(没有 XML 配置):
带有 GUI 版本的完整示例可以在这里找到: https: //github.com/ipolevoy/artemis-sanbox/blob/master/src/main/java/examples/
非常感谢任何帮助!
这里似乎存在一些误解......
CoreQueueConfiguration首先,你的“无效”的原因是它无效。它无效,因为您尚未指定队列将绑定到的地址的名称。当代理出现表明配置无效时,应该记录如下内容:
WARN [org.apache.activemq.artemis.core.server] AMQ222275: Failed to deploy queue <queue name>: null
Run Code Online (Sandbox Code Playgroud)
正如JMS 到核心映射文档中所述,JMS 队列是一个核心地址和一个同名的任播核心队列。因此,您应该使用这样的配置:
WARN [org.apache.activemq.artemis.core.server] AMQ222275: Failed to deploy queue <queue name>: null
Run Code Online (Sandbox Code Playgroud)
我的猜测是,事情部分正常,因为默认情况下,核心 JMS 客户端将自动创建它需要的目标,因此无论您指定什么,您在 JNDI 属性中配置的任何内容都将自动创建CoreQueueConfiguration。如果您不想自动创建 JMS 目标所需的底层地址和队列,那么您应该使用相应的地址设置来禁用它。还有一些设置可以在不再使用地址和队列时自动删除它们(即当消息计数 = 0 且消费者计数 = 0 时),您可能也想禁用它们。这是一个例子:
coreQueueConfiguration.setAddress("Queue123").setName("Queue123").setDurable(true).setRoutingType(org.apache.activemq.artemis.api.core.RoutingType.ANYCAST);
Run Code Online (Sandbox Code Playgroud)
其次,JNDI 配置在这段文档中进行了解释:
JMS 目标通常也通过 JNDI 查找。与连接工厂一样,可以使用 JNDI 上下文环境中的特殊属性来配置目标。属性名称应遵循以下模式:
queue.<jndi-binding>或topic.<jndi-binding>。属性值应该是 Apache ActiveMQ Artemis 服务器托管的队列的名称。
这解释了为什么您需要这一行:
server.getAddressSettingsRepository().addMatch("#", new AddressSettings()
.setAutoCreateQueues(false)
.setAutoDeleteQueues(false)
.setAutoCreateAddresses(false)
.setAutoDeleteAddresses(false));
Run Code Online (Sandbox Code Playgroud)
该文档还指出:
还可以查找尚未在 JNDI 上下文环境中显式配置的 JMS 目标。这可以在查找字符串中使用
dynamicQueues/或。dynamicTopics/例如,如果客户端想要查找上述“OrderQueue”,它可以简单地通过使用字符串“dynamicQueues/OrderQueue”来完成。dynamicQueues/请注意,后面的文本dynamicTopics/必须与服务器上的目标名称完全对应。
这意味着您可以省略上述行并使用这种查找:
jndi.put("queue.queue/Queue123", "Queue123");
Run Code Online (Sandbox Code Playgroud)
也就是说,目前还不清楚为什么要在这里使用 JNDI,而不是简单地使用 JMS API 实例化目标。您可以通过删除所有 JNDI 代码来大幅简化该代码,例如:
Queue jmsQueue = (Queue) initialContext.lookup("dynamicQueues/Queue123");
Run Code Online (Sandbox Code Playgroud)
要获得队列的控制权,请使用如下命令:
QueueControl coreQueueControl = (QueueControl) server.getManagementService().getResource(org.apache.activemq.artemis.api.core.management.ResourceNames.QUEUE + "Queue123");
Run Code Online (Sandbox Code Playgroud)
要浏览队列,您可以使用javax.jms.QueueBrowser. 网上有很多这方面的教程。
最后,在我们添加了对 AMQP、MQTT 和 OpenWire 的支持之后,我们在 2.0.0 版本发布之前就决定弃用 JMS 配置和管理位。此时,将配置和管理简化为仅核心资源(即地址、队列和路由类型)是有意义的。拥有所有核心内容加上JMS 的相应配置和管理肯定会给用户带来困惑,并且也很难维护。我们花了相当多的时间更新文档,以解释所有内容如何从各种支持的协议和 API 映射到核心资源。本文档提供的概述可能会对您有所帮助。
| 归档时间: |
|
| 查看次数: |
5352 次 |
| 最近记录: |