我正在运行 ActiveMQ Artemis 2.28.0,其代理配置如下所示。我留下了我认为相关的东西(主要是默认设置)。
我确信该文件确实被使用,因为如果我禁用自动创建队列,例如我确实会收到预期的错误,但在我的用例中其他设置似乎被忽略。
<configuration xmlns="urn:activemq"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xi="http://www.w3.org/2001/XInclude"
xsi:schemaLocation="urn:activemq /schema/artemis-configuration.xsd">
<core xmlns="urn:activemq:core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:activemq:core ">
<address-settings>
<!-- if you define auto-create on certain queues, management has to be auto-create -->
<address-setting match="activemq.management#">
<dead-letter-address>DLQ</dead-letter-address>
<expiry-address>ExpiryQueue</expiry-address>
<redelivery-delay>0</redelivery-delay>
<!-- with -1 only the global-max-size is in use for limiting -->
<max-size-bytes>-1</max-size-bytes>
<message-counter-history-day-limit>10</message-counter-history-day-limit>
<address-full-policy>PAGE</address-full-policy>
<auto-create-queues>true</auto-create-queues>
<auto-create-addresses>true</auto-create-addresses>
</address-setting>
<!--default for catch all-->
<address-setting match="#">
<dead-letter-address>DLQ</dead-letter-address>
<expiry-address>ExpiryQueue</expiry-address>
<redelivery-delay>0</redelivery-delay>
<max-size-bytes>-1</max-size-bytes>
<max-size-messages>-1</max-size-messages>
<page-size-bytes>10M</page-size-bytes>
<max-read-page-messages>-1</max-read-page-messages>
<max-read-page-bytes>20M</max-read-page-bytes>
<message-counter-history-day-limit>10</message-counter-history-day-limit>
<address-full-policy>PAGE</address-full-policy>
<auto-create-queues>true</auto-create-queues>
<auto-create-addresses>true</auto-create-addresses>
<auto-delete-queues>false</auto-delete-queues>
<auto-delete-addresses>false</auto-delete-addresses>
<auto-delete-created-queues>false</auto-delete-created-queues>
<default-exclusive-queue>false</default-exclusive-queue>
<default-max-consumers>-1</default-max-consumers>
</address-setting>
</address-settings>
<address-queue-scan-period>-1</address-queue-scan-period>
<addresses>
<address name="DLQ">
<anycast>
<queue name="DLQ" />
</anycast>
</address>
<address name="ExpiryQueue">
<anycast>
<queue name="ExpiryQueue" />
</anycast>
</address>
</addresses>
</core>
</configuration>
通过这些设置,我有以下期望:
但是,我观察到的行为如下:
1
,即使默认设置为 -1
auto-delete-queues
设置为 false
作为一种可能的解决方法,我还添加了
address-queue-scan-period
值,但这不会对观察到的行为产生影响。
这是创建的痕迹,显示了不正确的 maxConsumers 值
2023-06-15 15:56:05,251 DEBUG [org.apache.activemq.artemis.core.server.plugin.impl] AMQ843006: beforeCreateQueue called with queueConfig: QueueConfiguration [id=null, name=C7GN9YMV1P53I5PI.receiver, address=linda.acc.train.behaviour.12, routingType=MULTICAST, filterString=SubscriptionId='C7GN9YMV1P53I5PI' OR SubscriptionId IS NULL, durable=null, user=admin, maxConsumers=1, exclusive=false, groupRebalance=false, groupRebalancePauseDispatch=false, groupBuckets=-1, groupFirstKey=null, lastValue=false, lastValueKey=null, nonDestructive=false, purgeOnNoConsumers=false, enabled=true, consumersBeforeDispatch=0, delayBeforeDispatch=-1, consumerPriority=null, autoDelete=false, autoDeleteDelay=0, autoDeleteMessageCount=0, ringSize=-1, configurationManaged=null, temporary=null, autoCreateAddress=true, internal=null, transient=null, autoCreated=null]
当消费者关闭时,下面的日志指示队列和地址被销毁,这与我的设置不匹配。
2023-06-15 15:56:35,559 INFO [org.apache.activemq.artemis.core.server.plugin.impl] AMQ841006: closed consumer ID: 0, with consumer Session: 5ef8b4b4-0b84-11ee-be26-d6283bc2e653, failed: false
2023-06-15 15:56:35,568 DEBUG [org.apache.activemq.artemis.core.server.plugin.impl] AMQ843007: beforeDestroyQueue called with queueName: C7GN9YMV1P53I5PI.receiver, session: ServerSessionImpl(), checkConsumerCount: true, removeConsumers: false, autoDeleteAddress: true
此时我真的不知道我是否遇到了错误,或者我是否误解了设置参数。
我相信您误解了自动地址和队列创建功能。自动地址和队列创建仅适用于正常操作不会创建地址或队列的情况。例如,如果 JMS 生产者向 broker.xml
中尚不存在的 JMS 队列发送消息,则使用默认设置,将创建相应的地址和选播队列,并且消息将存储在该队列中。也就是说,从技术上讲,队列是在多播(即发布/订阅)用例中自动创建的,无论
broker.xml
中的自动创建设置如何。文档通常将这些队列称为“订阅队列”。例如,如果 JMS 使用者订阅了一个 JMS 主题,并且该主题的相应地址已在
broker.xml
中配置,那么无论自动创建配置如何,都会自动创建该使用者订阅的多播队列。这是因为对于正常的多播语义来说,订阅队列是“必需的”。如果订阅队列不是自动创建的,那么您必须在
broker.xml
中为每个订阅者手动配置多播队列,这是不现实的。从历史上看,这种行为早在出现任何其他地址和队列自动创建概念之前就已经存在了。
此外,无论
default-*
address-settings
的配置如何(例如
default-max-consumers
、
default-exclusive
),某些设置都会应用于订阅队列。这是由于特定订阅队列的性质造成的。例如,在 JMS 中,订阅可以是共享的或非共享的,也可以是持久的或非持久的。非共享订阅队列的最大消费者数量为
1
,因为它们永远不应该被共享(即有 > 1 个消费者)。我在 Artemis 和 AMQP 的“持久主题”上无数次地抓狂 事实证明你需要两件事:
您的代理 xml 中的 auto-delete-queues = false
receiver, errR := session.NewReceiver(
amqp.LinkSourceAddress("someaddress::go"),
amqp.LinkTargetAddress("someaddress::go"),
amqp.LinkCredit(10),
amqp.LinkSourceFilter("com.microsoft:session-filter", 1000, "invalid"),
amqp.LinkPropertyInt64("some", 1000),
amqp.LinkName("name"),
)
或者在 .NET 中也是如此:
var session = new Session(connection);
var receiverLink = new ReceiverLink(session, "100", "someaddress::net");
只有这样,您才能获得在会话中幸存下来的订阅者队列,并且您可以在地址后面的同一队列上重新连接客户端(上面示例中的 someaddress->go 或 someaddress->net...)某个地址::去
某个地址::网络