虚拟主题在使用 ActiveMQ 5.x 的连接工厂时有效,但在 Artemis 的连接工厂中无效
Virtual topics work when using ActiveMQ 5.x's connection factory, but not Artemis' connection factory
我正在将现有代码从使用 ActiveMQ 5.x 迁移到使用 Artemis。使用 org.apache.activemq.ActiveMQConnectionFactory
时,我的虚拟主题消费者队列中有发送到虚拟主题的消息排队给它们。使用 org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory
时,它们不会。
使用 ActiveMQ 5.x 的连接工厂为虚拟主题工作的连接池配置是:
<bean id="jmsFactory" class="org.apache.activemq.jms.pool.PooledConnectionFactory" init-method="start" destroy-method="stop">
<property name="connectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="failover:${activemq.broker}" />
<property name="userName" value="${activemq.credentials.username}"/>
<property name="password" value="${activemq.credentials.password}"/>
</bean>
</property>
<property name="maxConnections" value="${activemq.connectionPool.size}" />
<property name="maximumActiveSessionPerConnection" value="${activemq.connectionPool.sessionsPerConnection}" />
</bean>
不能使用 Artemis 连接工厂的虚拟主题的连接池配置是:
<bean id="jmsConnectionFactory" class="org.apache.activemq.jms.pool.PooledConnectionFactory" init-method="start" destroy-method="stop">
<property name="connectionFactory">
<bean class="org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory">
<constructor-arg name="url" value="${activemq.broker}"/>
<constructor-arg name="user" value="${activemq.credentials.username}"/>
<constructor-arg name="password" value="${activemq.credentials.password}"/>
</bean>
</property>
<property name="maxConnections" value="${activemq.connectionPool.size}" />
<property name="maximumActiveSessionPerConnection" value="${activemq.connectionPool.sessionsPerConnection}" />
</bean>
对于虚拟话题,我的消费者是Camel路由,生产者是Spring的JmsTemplate
class的实例。生产者被配置为生产模式 VirtualTopic.Foo
中的主题,消费者被配置为从模式 jms:queue:VirtualTopic.Foo::Consumer.MyApplication.VirtualTopic.Foo
中的 Camel 端点消费。
jms
Camel 组件配置了上面的 jmsFactory
bean,JmsTemplate
实例也是如此:
<bean id="jms" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory" ref="jmsFactory"/>
<property name="deliveryPersistent" value="${activemq.delivery.persistent}"/>
</bean>
理想情况下,我可以使用 Artemis 的 ActiveMQConnectionFactory
。是什么导致发送到虚拟主题的消息在使用时没有被分派到消费者队列?
这可能与所使用的 JMS 驱动程序有关,也可能无关。如何以及何时创建虚拟主题及其消费者似乎是一个问题。下面详细介绍了我是如何实现这一目标的,但简而言之,请确保在创建消费者之前创建虚拟主题。
我注意到我的一个虚拟主题 VirtualTopic.Fig
正在运行,但我的其他虚拟主题 none 正在运行。虚拟主题的所有消费者队列都是使用完全限定的队列名称创建的,如 Artemis documentation 中所述(订阅队列 VirtualTopic.Fig::Consumer.A.VirtualTopic.Fig
而不是 Consumer.A.VirtualTopic.Fig
)。我 运行 listAddresses
管理命令并看到虚拟主题的输出:
name size consumers anycast multicast
-----------------------------------------------------------------------
VirtualTopic.Apple - 1 Y -
VirtualTopic.Banana - 1 Y -
VirtualTopic.Cantaloupe - 1 Y -
VirtualTopic.DragonFruit - 1 Y -
VirtualTopic.ElderBerry - 1 Y -
VirtualTopic.Fig - 1 Y Y
-----------------------------------------------------------------------
使用 updateAddress
命令 (updateAddress VirtualTopic.DragonFruit ANYCAST,MULTICAST
),我更新了 VirtualTopic.DragonFruit
以具有多播路由,重新启动了我的消费者,其中大部分开始接收消息。假设剩下的消费者没有工作,因为它们是在创建主题之前创建的,并且绑定到地址的任播版本,对于每个地址,我:
- 关闭所有从虚拟主题生成或使用的应用程序。
- 使用
destroyQueue
命令 (destroyQueue Consumer.A.VirtualTopic.DragonFruit true true
) 销毁了消费者队列。
- 使用
deleteAddress
命令 (deleteAddress VirtualTopic.DragonFruit
) 删除了主题。
- 使用
createAddress
命令 (createAddress VirtualTopic.DragonFruit MULTICAST
) 将主题创建为多播地址。
- 再次启动所有应用程序。
手动创建虚拟主题后,一切开始工作。 listAddresses
命令的新输出是:
name size consumers anycast multicast
-----------------------------------------------------------------------
VirtualTopic.Apple - 1 - Y
VirtualTopic.Banana - 1 - Y
VirtualTopic.Cantaloupe - 1 - Y
VirtualTopic.DragonFruit - 1 - Y
VirtualTopic.ElderBerry - 1 - Y
VirtualTopic.Fig - 1 - Y
-----------------------------------------------------------------------
并且 listQueues
命令的输出显示消费者现在正在接收消息:
name size consumers enqueued dequeued
----------------------------------------------------------------------------------
Consumer.A.VirtualTopic.Apple 0 1 88 88
Consumer.A.VirtualTopic.Banana 0 1 4 4
Consumer.A.VirtualTopic.Cantaloupe 0 1 12 12
Consumer.A.VirtualTopic.DragonFruit 0 1 74 74
Consumer.A.VirtualTopic.ElderBerry 0 1 1776 1776
Consumer.A.VirtualTopic.Fig 0 1 75 75
----------------------------------------------------------------------------------
我正在将现有代码从使用 ActiveMQ 5.x 迁移到使用 Artemis。使用 org.apache.activemq.ActiveMQConnectionFactory
时,我的虚拟主题消费者队列中有发送到虚拟主题的消息排队给它们。使用 org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory
时,它们不会。
使用 ActiveMQ 5.x 的连接工厂为虚拟主题工作的连接池配置是:
<bean id="jmsFactory" class="org.apache.activemq.jms.pool.PooledConnectionFactory" init-method="start" destroy-method="stop">
<property name="connectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="failover:${activemq.broker}" />
<property name="userName" value="${activemq.credentials.username}"/>
<property name="password" value="${activemq.credentials.password}"/>
</bean>
</property>
<property name="maxConnections" value="${activemq.connectionPool.size}" />
<property name="maximumActiveSessionPerConnection" value="${activemq.connectionPool.sessionsPerConnection}" />
</bean>
不能使用 Artemis 连接工厂的虚拟主题的连接池配置是:
<bean id="jmsConnectionFactory" class="org.apache.activemq.jms.pool.PooledConnectionFactory" init-method="start" destroy-method="stop">
<property name="connectionFactory">
<bean class="org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory">
<constructor-arg name="url" value="${activemq.broker}"/>
<constructor-arg name="user" value="${activemq.credentials.username}"/>
<constructor-arg name="password" value="${activemq.credentials.password}"/>
</bean>
</property>
<property name="maxConnections" value="${activemq.connectionPool.size}" />
<property name="maximumActiveSessionPerConnection" value="${activemq.connectionPool.sessionsPerConnection}" />
</bean>
对于虚拟话题,我的消费者是Camel路由,生产者是Spring的JmsTemplate
class的实例。生产者被配置为生产模式 VirtualTopic.Foo
中的主题,消费者被配置为从模式 jms:queue:VirtualTopic.Foo::Consumer.MyApplication.VirtualTopic.Foo
中的 Camel 端点消费。
jms
Camel 组件配置了上面的 jmsFactory
bean,JmsTemplate
实例也是如此:
<bean id="jms" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory" ref="jmsFactory"/>
<property name="deliveryPersistent" value="${activemq.delivery.persistent}"/>
</bean>
理想情况下,我可以使用 Artemis 的 ActiveMQConnectionFactory
。是什么导致发送到虚拟主题的消息在使用时没有被分派到消费者队列?
这可能与所使用的 JMS 驱动程序有关,也可能无关。如何以及何时创建虚拟主题及其消费者似乎是一个问题。下面详细介绍了我是如何实现这一目标的,但简而言之,请确保在创建消费者之前创建虚拟主题。
我注意到我的一个虚拟主题 VirtualTopic.Fig
正在运行,但我的其他虚拟主题 none 正在运行。虚拟主题的所有消费者队列都是使用完全限定的队列名称创建的,如 Artemis documentation 中所述(订阅队列 VirtualTopic.Fig::Consumer.A.VirtualTopic.Fig
而不是 Consumer.A.VirtualTopic.Fig
)。我 运行 listAddresses
管理命令并看到虚拟主题的输出:
name size consumers anycast multicast
-----------------------------------------------------------------------
VirtualTopic.Apple - 1 Y -
VirtualTopic.Banana - 1 Y -
VirtualTopic.Cantaloupe - 1 Y -
VirtualTopic.DragonFruit - 1 Y -
VirtualTopic.ElderBerry - 1 Y -
VirtualTopic.Fig - 1 Y Y
-----------------------------------------------------------------------
使用 updateAddress
命令 (updateAddress VirtualTopic.DragonFruit ANYCAST,MULTICAST
),我更新了 VirtualTopic.DragonFruit
以具有多播路由,重新启动了我的消费者,其中大部分开始接收消息。假设剩下的消费者没有工作,因为它们是在创建主题之前创建的,并且绑定到地址的任播版本,对于每个地址,我:
- 关闭所有从虚拟主题生成或使用的应用程序。
- 使用
destroyQueue
命令 (destroyQueue Consumer.A.VirtualTopic.DragonFruit true true
) 销毁了消费者队列。 - 使用
deleteAddress
命令 (deleteAddress VirtualTopic.DragonFruit
) 删除了主题。 - 使用
createAddress
命令 (createAddress VirtualTopic.DragonFruit MULTICAST
) 将主题创建为多播地址。 - 再次启动所有应用程序。
手动创建虚拟主题后,一切开始工作。 listAddresses
命令的新输出是:
name size consumers anycast multicast
-----------------------------------------------------------------------
VirtualTopic.Apple - 1 - Y
VirtualTopic.Banana - 1 - Y
VirtualTopic.Cantaloupe - 1 - Y
VirtualTopic.DragonFruit - 1 - Y
VirtualTopic.ElderBerry - 1 - Y
VirtualTopic.Fig - 1 - Y
-----------------------------------------------------------------------
并且 listQueues
命令的输出显示消费者现在正在接收消息:
name size consumers enqueued dequeued
----------------------------------------------------------------------------------
Consumer.A.VirtualTopic.Apple 0 1 88 88
Consumer.A.VirtualTopic.Banana 0 1 4 4
Consumer.A.VirtualTopic.Cantaloupe 0 1 12 12
Consumer.A.VirtualTopic.DragonFruit 0 1 74 74
Consumer.A.VirtualTopic.ElderBerry 0 1 1776 1776
Consumer.A.VirtualTopic.Fig 0 1 75 75
----------------------------------------------------------------------------------