1

我正在使用 ActiveMQ Artemis 消息系统,并且正在使用 STOMP (stomp.py) 测试我的设置。

我在 Artemis 上创建了一个名为 的“地址” Site.SOF.Order.Fulfillment.Submission.ActiveOmni.Topic,并为其附加了两个队列:

  • Site.SOF.Order.Fulfillment.Submission.ActiveOmni.queue(多播)
  • Site.SOF.Order.Fulfillment.Submission.ActiveOmni.log.queue(多播)

以下是导出的绑定:

<bindings>
   <address-binding routing-types="ANYCAST" name="DLQ" id="2"/>
   <address-binding routing-types="ANYCAST" name="ExpiryQueue" id="6"/>
   <address-binding routing-types="MULTICAST" name="activemq.notifications" id="10"/>
   <address-binding routing-types="MULTICAST" name="Site.SOF.Order.Fulfillment.Submission.Topic" id="92"/>
   <queue-binding address="Site.SOF.Order.Fulfillment.Submission.Topic" filter-string="" name="Site.SOF.Order.Fulfillment.Submission.log.Queue" id="97" routing-type="MULTICAST"/>
   <queue-binding address="DLQ" filter-string="" name="DLQ" id="4" routing-type="ANYCAST"/>
   <queue-binding address="ExpiryQueue" filter-string="" name="ExpiryQueue" id="8" routing-type="ANYCAST"/>
   <queue-binding address="Site.SOF.Order.Fulfillment.Submission.Topic" filter-string="" name="Site.SOF.Order.Fulfillment.Submission.ActiveOmni.Queue" id="94" routing-type="MULTICAST"/>
</bindings>

我创建了一个有权访问的用户Site.*

那么如何访问队列呢?例如,如果我像这样使用 stomp.py 命令行工具:

> subscribe Site.SOF.Order.Fulfillment.Submission.ActiveOmni.queue

我得到错误:

[username] does not have permission='CREATE_ADDRESS' on address Site.SOF.Order.Fulfillment.Submission.ActiveOmni.queue

所以我尝试添加/queue/到前面,正如我在教程中看到的那样

> subscribe /queue/Site.SOF.Order.Fulfillment.Submission.ActiveOmni.queue

但我得到同样的错误:

[username] does not have permission='CREATE_ADDRESS' on address /queue/Site.SOF.Order.Fulfillment.Submission.ActiveOmni.queue

我可以毫无问题地发送到主题/地址。以下结果导致两个队列中都出现“hello”消息。

send Site.SOF.Order.Fulfillment.Submission.ActiveOmni.Topic "hello"

这是我缺少的命名约定吗?还是一种指定主题与队列的方法?我在这里遗漏了什么太明显而无法清楚记录的东西?

4

1 回答 1

2

让我先提供一些背景信息...

ActiveMQ Artemis 地址模型包括 3 个主要元素——地址、队列和路由类型。这些是低级实体,用于为代理支持的所有不同协议和配置实现所有不同语义。

相比之下,STOMP 只支持模棱两可的“目的地”。STOMP 1.2 规范说明了目的地:

STOMP 服务器被建模为一组可以向其发送消息的目的地。STOMP 协议将目的地视为不透明的字符串,并且它们的语法是特定于服务器实现的。此外,STOMP 没有定义目的地的交付语义应该是什么。目的地的传递或“消息交换”语义可能因服务器而异,甚至因目的地而异。这允许服务器使用 STOMP 可以支持的语义进行创造性。

在核心地址模型中,消息被发送到地址并从队列中消费。地址和队列是独立命名的,因此核心生产者和消费者使用的名称可以不同。

ActiveMQ Artemis 支持 STOMP 目标的点对点和发布/订阅语义。您可以在最新的 ActiveMQ Artemis STOMP 文档中阅读有关如何配置这些语义的更多信息。

在 STOMP 点对点用例中,一条消息被发送到一个目的地并从该目的地消费。STOMP 生产者和消费者使用的名称是相同的。为了支持这些语义,代理使用一个核心地址和一个同名的核心任播队列。

在 STOMP 发布/订阅用例中,客户端在目标上创建订阅,然后可以使用该订阅接收发送到该目标的消息。STOMP 订阅者和生产者使用的名称相同。为了支持这些语义,代理使用一个核心地址和一个具有不同名称的核心多播队列。核心队列的名称由代理自动生成。然后订阅者可以直接从底层核心订阅队列接收消息。

所有这些东西都是为 STOMP 客户端在幕后完成的,但是了解 STOMP 如何映射到 ActiveMQ Artemis 的地址模型很重要,这样您就可以适当地配置事物


在您的情况下,您已经配置了一个带有 2 个多播队列的地址,并且您正在尝试从这些队列中消费。这个用例是点对点和发布/订阅之间的混合,因为您有静态定义的队列(即不是由代理自动创建以响应订阅者的队列)但队列是多播的。这些队列就像静态配置的持久订阅。要直接访问队列,您需要使用客户端的完全限定队列名称(即 FQQN)。FQQN 遵循这样的模式,<address>::<queue>因此在您的情况下,您可以使用

Site.SOF.Order.Fulfillment.Submission.ActiveOmni.Topic::Site.SOF.Order.Fulfillment.Submission.ActiveOmni.queue

或者

Site.SOF.Order.Fulfillment.Submission.ActiveOmni.Topic::Site.SOF.Order.Fulfillment.Submission.ActiveOmni.log.queue
于 2020-03-11T16:25:40.797 回答