我怎样才能从 Apache Artemis 获得与从带有通配符 JMS 侦听器的经典 ActiveMQ 获得的行为相同的行为
How can I get the same behaviour From Apache Artemis as I get from the classic ActiveMQ with wildcard JMS listener
首先,让我解释一下我对经典 ActiveMQ 的尝试,它完美地满足了我的要求:
我有几个带有命名模板的队列,每个队列代表一个租户(客户)。命名模式就像 queue.<<tenant-id>>.event
一样,在这里,为了简单起见,我使用 test1 到 test5。
多个生产者根据请求的租户将消息放在这些不同的队列中。
我的 ActiveMQ 队列在 Web 控制台中看起来像这样:
Queues in the classic ActiveMQ
然后我使用通配符启动 Spring JMS 侦听器,以便能够使用一个侦听器读取所有这些队列。代码是这样的:
@JmsListener(destination = "queue.>")
public void receiveMessage(Event event) {
//Process the event message
}
我观察到的我无法配置 Artemis 做同样的事情是:
- 使用通配符监听 ActiveMQ 队列没有创建新队列(监听队列)
- 使用通配符侦听器使用消息实际上会减少实际队列中待处理消息的数量。
- 通配符侦听器实际上会相当公平地读取来自所有队列的消息。它仍然尊重每个队列上的 FIFO,但不会尊重它跨队列。例如,当我在
queue.test1.event
中放入 100 条消息,然后才在 queue.test2.event
中添加 100 条消息时,如果我启动通配符侦听器,它就会开始公平地从两个队列中读取消息,尽管所有消息in queue.test2.event
queue 基本上是在 queue.test1.event
. 的100条消息之后添加的
我需要功能 #2 和 #3。第一个只是观察,我认为这是我在 Artemis 中出现问题的根本原因。
现在,当我搬到 Artemis 时发生的事情是:
通配符模式有点不同,但我做了同样的场景。听众看起来像:
@JmsListener(destination = "queue.#")
public void receiveMessage(Event event) {
//Process the event message
}
如您所见,通配符模板已更改为 queue.#
,以便能够从所有这些队列中读取。
我的 Artemis 队列在 Web 控制台中看起来像这样:
Queues in the Artemis,
我在 Web 控制台上的观察显示我无法在此处实现相同的目标:
- 正如你在图片中看到的那样,我在其中放置消息的原始队列中的
message count
数量仍然保留,尽管其中只剩下 44 个待处理(查看 message count
of queue.#
),其余部分已被通配符侦听器读取。
这可能会导致我的存储问题,因为我的所有消息都已保留,我也无法处理消息过期。
- 正如您在图片中看到的,监听器创建了另一个名为
queue.#
的队列,这似乎是 Artemis 在内部将来自其他队列的消息复制到其中。
不是问题,只是观察。
- 它尊重所有队列的 FIFO,我猜这是因为 Artemis 正在执行从原始队列到通配符队列的复制。
这对我来说是个大问题。虽然我仍然希望它尊重每个队列中的 FIFO,但我也希望它开始使用来自其他队列的消息。因为,如果一个客户正在处理巨大的任务,它不应该阻止其他人继续他们的任务。
PS1:我限制两个测试中的侦听器一次只使用一条消息以便能够正确测试它。
PS2:如果你想知道为什么我不使用经典的 ActiveMQ,如果它完全满足我的需要,答案是:Apache 将使 Artemis 成为它的主要版本(一旦达到一定程度的成熟度)在未来,我想与其网站上的 roadmap.Quote 保持一致:
Once Artemis reaches a sufficient level of feature parity with the "Classic" code-base it will become the next major version of ActiveMQ
PS3:我正在使用 spring-boot 及其启动包来连接和 put/consume 消息。
PS4:我对解决方案和安装都使用默认配置。
简而言之,ActiveMQ Artemis 不支持通配符消费者。它仅支持具有相似但不同语义的通配符 地址 (如您的 的答案中所述)。
随时打开 an issue 请求实现此功能。
首先,让我解释一下我对经典 ActiveMQ 的尝试,它完美地满足了我的要求:
我有几个带有命名模板的队列,每个队列代表一个租户(客户)。命名模式就像 queue.<<tenant-id>>.event
一样,在这里,为了简单起见,我使用 test1 到 test5。
多个生产者根据请求的租户将消息放在这些不同的队列中。
我的 ActiveMQ 队列在 Web 控制台中看起来像这样: Queues in the classic ActiveMQ
然后我使用通配符启动 Spring JMS 侦听器,以便能够使用一个侦听器读取所有这些队列。代码是这样的:
@JmsListener(destination = "queue.>")
public void receiveMessage(Event event) {
//Process the event message
}
我观察到的我无法配置 Artemis 做同样的事情是:
- 使用通配符监听 ActiveMQ 队列没有创建新队列(监听队列)
- 使用通配符侦听器使用消息实际上会减少实际队列中待处理消息的数量。
- 通配符侦听器实际上会相当公平地读取来自所有队列的消息。它仍然尊重每个队列上的 FIFO,但不会尊重它跨队列。例如,当我在
queue.test1.event
中放入 100 条消息,然后才在queue.test2.event
中添加 100 条消息时,如果我启动通配符侦听器,它就会开始公平地从两个队列中读取消息,尽管所有消息inqueue.test2.event
queue 基本上是在queue.test1.event
. 的100条消息之后添加的
我需要功能 #2 和 #3。第一个只是观察,我认为这是我在 Artemis 中出现问题的根本原因。
现在,当我搬到 Artemis 时发生的事情是: 通配符模式有点不同,但我做了同样的场景。听众看起来像:
@JmsListener(destination = "queue.#")
public void receiveMessage(Event event) {
//Process the event message
}
如您所见,通配符模板已更改为 queue.#
,以便能够从所有这些队列中读取。
我的 Artemis 队列在 Web 控制台中看起来像这样: Queues in the Artemis,
我在 Web 控制台上的观察显示我无法在此处实现相同的目标:
- 正如你在图片中看到的那样,我在其中放置消息的原始队列中的
message count
数量仍然保留,尽管其中只剩下 44 个待处理(查看message count
ofqueue.#
),其余部分已被通配符侦听器读取。这可能会导致我的存储问题,因为我的所有消息都已保留,我也无法处理消息过期。
- 正如您在图片中看到的,监听器创建了另一个名为
queue.#
的队列,这似乎是 Artemis 在内部将来自其他队列的消息复制到其中。不是问题,只是观察。
- 它尊重所有队列的 FIFO,我猜这是因为 Artemis 正在执行从原始队列到通配符队列的复制。
这对我来说是个大问题。虽然我仍然希望它尊重每个队列中的 FIFO,但我也希望它开始使用来自其他队列的消息。因为,如果一个客户正在处理巨大的任务,它不应该阻止其他人继续他们的任务。
PS1:我限制两个测试中的侦听器一次只使用一条消息以便能够正确测试它。
PS2:如果你想知道为什么我不使用经典的 ActiveMQ,如果它完全满足我的需要,答案是:Apache 将使 Artemis 成为它的主要版本(一旦达到一定程度的成熟度)在未来,我想与其网站上的 roadmap.Quote 保持一致:
Once Artemis reaches a sufficient level of feature parity with the "Classic" code-base it will become the next major version of ActiveMQ
PS3:我正在使用 spring-boot 及其启动包来连接和 put/consume 消息。
PS4:我对解决方案和安装都使用默认配置。
简而言之,ActiveMQ Artemis 不支持通配符消费者。它仅支持具有相似但不同语义的通配符 地址 (如您的
随时打开 an issue 请求实现此功能。