You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ActiveMQ消费者连接Broker时是否每次创建地址?特殊格式地址疑问

关于ActiveMQ Artemis自定义安全管理器中特殊格式地址授权事件的疑问

我们实现ActiveMQSecurityManager5接口自定义安全管理器时发现:当已有<address-name>地址存在,新订阅者/消费者连接Broker时,会触发CheckType.CREATE_ADDRESS授权事件,对应的地址格式为<address-name>::<client-id>.<address-name>;在此事件之前,同样的地址还会触发CheckType.CREATE_NON_DURABLE_QUEUE事件。

我对为何会创建这种FQQN队列格式的新地址感到困惑,这是否属于ActiveMQ路由逻辑的细节?


编辑补充

添加了订阅时CREATE_ADDRESS事件的栈追踪信息。ActiveMQSecurityManager5类中的authorize方法如下:

@Override
public boolean authorize(Subject subject, Set<Role> roles, CheckType checkType, String address) {
    System.out.println("Checktype: " + checkType);
    System.out.println("Address: "+ address);
    if (checkType.equals(CheckType.CREATE_ADDRESS) && address.contains("::")) {
      new Exception("trace").printStackTrace();
    }
    return true;
}

以下是该异常的栈追踪信息,其中newaddress是消费者尝试连接的地址,bad是消费者的client ID:

Checktype: CREATE_ADDRESS
Address: newaddress::bad.newaddress
java.lang.Exception: trace
    at org.test.JwtPlugin.authorize(JwtPlugin.java:73)
    at org.apache.activemq.artemis.core.security.impl.SecurityStoreImpl.check(SecurityStoreImpl.java:344)
    at org.apache.activemq.artemis.core.server.impl.ServerSessionImpl.securityCheck(ServerSessionImpl.java:527)
    at org.apache.activemq.artemis.core.server.impl.ServerSessionImpl.createQueue(ServerSessionImpl.java:770)
    at org.apache.activemq.artemis.core.protocol.mqtt.MQTTSubscriptionManager.findOrCreateQueue(MQTTSubscriptionManager.java:187)
    at org.apache.activemq.artemis.core.protocol.mqtt.MQTTSubscriptionManager.createQueueForSubscription(MQTTSubscriptionManager.java:174)
    at org.apache.activemq.artemis.core.protocol.mqtt.MQTTSubscriptionManager.addSubscription(MQTTSubscriptionManager.java:108)
    at org.apache.activemq.artemis.core.protocol.mqtt.MQTTSubscriptionManager.addSubscriptions(MQTTSubscriptionManager.java:310)
    at org.apache.activemq.artemis.core.protocol.mqtt.MQTTProtocolHandler.handleSubscribe(MQTTProtocolHandler.java:382)
    at org.apache.activemq.artemis.core.protocol.mqtt.MQTTProtocolHandler.act(MQTTProtocolHandler.java:179)
    at org.apache.activemq.artemis.utils.actors.Actor.doTask(Actor.java:32)
    at org.apache.activemq.artemis.utils.actors.ProcessorBase.executePendingTasks(ProcessorBase.java:69)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    at org.apache.activemq.artemis.utils.ActiveMQThreadFactory$1.run(ActiveMQThreadFactory.java:120)

问题解答

这种格式的地址属于ActiveMQ Artemis处理MQTT订阅时的内部路由逻辑细节,具体原因如下:

  1. MQTT订阅的队列生成规则
    从栈追踪能看到,整个流程由MQTTSubscriptionManager触发。MQTT协议本身没有"地址-队列"的分离概念,Artemis为了适配MQTT,会给每个MQTT订阅生成专属队列:
  • 队列名称格式为<client-id>.<address-name>,确保每个客户端的订阅队列唯一
  • 这里的<address-name>::<client-id>.<address-name>是**Fully Qualified Queue Name (FQQN)**格式,用::分隔地址和队列名,是Artemis内部用来唯一标识队列的规范格式
  1. 为何触发CREATE_ADDRESS事件
    当创建这个专属队列时,Artemis的安全检查逻辑会把FQQN当作"地址"参数传入授权方法。这是因为在Artemis的安全模型中,队列的创建会关联到其对应的地址权限检查,而内部处理时会把FQQN格式的队列标识符传递给授权接口,从而触发了CREATE_ADDRESS事件。

  2. 事件顺序的逻辑

  • 先触发CREATE_NON_DURABLE_QUEUE:对应创建<client-id>.<address-name>这个非持久化队列的操作
  • 再触发CREATE_ADDRESS:是安全检查流程中对队列关联的FQQN格式标识符的额外权限校验,属于内部逻辑的一部分

这不是Bug,而是Artemis适配MQTT协议时,为了管理客户端专属订阅队列而产生的内部权限检查行为,属于路由和安全模型结合的细节。

内容的提问来源于stack exchange,提问作者TdBm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 07:54:53