在 ActiveMQ Artemis 中为每个消费者创建 DLQ

发布于 2025-01-11 13:07:59 字数 879 浏览 1 评论 0原文

我正在使用 JMS 消费来自 ActiveMQ Artemis 主题的消息。我的消费者直接连接到其消费者队列的 FQQN。像这样:

jmsTemplate.setDefaultDestinationName("Transactions.Client1::ConsumerA");

broker.xml 中的配置是:

<address-setting match="Transactions.*">
    <auto-create-dead-letter-resources>true</auto-create-dead-letter-resources>
    <dead-letter-address>Transactions.Retry</dead-letter-address>
</address-setting>

但是,DLQ 的名称将是 DLQ.Transactions.Client1,没有消费者名称。

我需要的是每个消费者都有自己的DLQ。类似DLQ.Transactions.Client1.ConsumerA。这可能吗?

编辑:

当我说“消费者”时,它可能(实际上)更像是“消费者群体”。例如,ConsumerAConsumerB 是两个完全不同的应用程序,(可能)具有多个运行实例并由自己的团队管理。这就是为什么我想要为每个人设置不同的 DLQ。

I'm consuming messages from an ActiveMQ Artemis topic using JMS. My consumers are connecting directly to the FQQN of their consumer queues. Like this:

jmsTemplate.setDefaultDestinationName("Transactions.Client1::ConsumerA");

And the configuration in the broker.xml is:

<address-setting match="Transactions.*">
    <auto-create-dead-letter-resources>true</auto-create-dead-letter-resources>
    <dead-letter-address>Transactions.Retry</dead-letter-address>
</address-setting>

But then, the name of the DLQ will be DLQ.Transactions.Client1, without the consumer name.

What I need is that each consumer has its own DLQ. Something like DLQ.Transactions.Client1.ConsumerA. Is this possible?

EDIT:

When I say "consumer", it may (actually) be more like a "consumer group". For example, ConsumerA and ConsumerB are two totally different applications, with (possibly) multiple running instances and managed by its own team. That's why I want a different DLQ for each one.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

银河中√捞星星 2025-01-18 13:07:59

无法将代理配置为自动创建名称包含最初发送消息的队列名称的死信队列。如中所述文档中,死信队列根据最初发送消息的地址以及任何配置的前缀和/或后缀来命名。

但是,消息本身将有一个名为 _AMQ_ORIG_QUEUE 的属性,其中包含消息最初路由的队列的名称。这意味着您可以将消费者与消息选择器一起使用(例如_AMQ_ORIG_QUEUE = 'ConsumerA'),以便消费者将接收最初路由到特定队列的消息。这在功能上等同于每个队列都有一个死信队列。

无论如何,您所说的“消费者名称”根本不是消费者的名称,至少从经纪人的角度来看不是。这只是队列的名称。

最终,不可能为每个队列配置一个死信队列。只能为每个地址配置一个死信队列。无论资源是手动创建(例如通过broker.xml)还是自动创建,都是如此。

It's not possible to configure the broker to auto-create a dead-letter queue whose name contains the name of the queue where the message was originally sent. As noted in the documentation, the dead-letter queue is named according to the address where the message was originally sent along with any configured prefix and/or suffix.

However, the message itself will have a property named _AMQ_ORIG_QUEUE which will contain the name of the queue where the message was originally routed. This means you can use a consumer with a message selector (e.g. _AMQ_ORIG_QUEUE = 'ConsumerA') so that the consumer will only receive messages which were originally routed to a particular queue. This is functionally equivalent to having a dead-letter queue per-queue.

For what it's worth, what you're calling the "consumer name" isn't the name of the consumer at all, at least not from the broker's point of view. It's just the name of the queue.

Ultimately it's just not possible to configure a dead-letter queue per-queue. It's only possible to configure a dead-letter queue per address. This is true whether the resources are create manually (e.g. via broker.xml) or automatically.

爱的十字路口 2025-01-18 13:07:59

贾斯汀·伯特伦的回答可能是大多数人应该做的。如果不是每个消费者应用程序具有不同的死信地址和到期地址的要求,我就会这么做。

就我而言,我使用 Diverts 解决了这个问题。

首先,制片人没有改变。它不断向主题 Transactions.Client1 发帖。

然后,我在 broker.xml 文件中配置了一个转移:

<divert name="Transactions.Divert">
    <address>Transactions.Client1</address>
    <forwarding-address>Transactions.Client1.ConsumerA</forwarding-address>
    <exclusive>false</exclusive>
</divert>

重要:
缺点是它无法扩展。如果我有 N 个客户和 M 个消费者,我将有 N×M 个转移。

然后,地址设置更改为(注意 match 属性中的两个星号):

<address-setting match="Transactions.*.*">
    <auto-create-dead-letter-resources>true</auto-create-dead-letter-resources>
    <dead-letter-address>Transactions.Retry</dead-letter-address>
</address-setting>

因此,当消息处理失败时,将在地址 Transactions.Retry 处创建一个名为 <代码>DLQ.Transactions.Client1.ConsumerA。

每个人都很高兴,除了运维人员,他必须在生产中配置一百多个转移。我希望他的 vim-fu 没事。

PS:提示:始终转移到具有相同前缀的地址(在示例中为“交易”)。当您必须在生产中配置集群时,这将使您的生活变得更加轻松。

Justin Bertram's answer is probably what most people should do. It is what I would have done if wasn't for the requirements of having different dead letter address and expiry address per consumer application.

In my case, I solved it using Diverts.

First, the producer wasn't changed. It keeps posting to the topic Transactions.Client1.

Then, I configured a divert in the broker.xml file:

<divert name="Transactions.Divert">
    <address>Transactions.Client1</address>
    <forwarding-address>Transactions.Client1.ConsumerA</forwarding-address>
    <exclusive>false</exclusive>
</divert>

IMPORTANT:
The downside is that it doesn't scale. If I have N clients and M consumers, I'll have N×M diverts.

Then, the address-settings was changed to (note the two asterisks in the match attribute):

<address-setting match="Transactions.*.*">
    <auto-create-dead-letter-resources>true</auto-create-dead-letter-resources>
    <dead-letter-address>Transactions.Retry</dead-letter-address>
</address-setting>

So, when the processing of a message fails, at the address Transactions.Retry will be created a queue named DLQ.Transactions.Client1.ConsumerA.

And everybody is happy, except the ops guy, who will have to configure more than a hundred diverts in production. I hope his vim-fu is OK.

PS: Just a tip: Always divert to addresses with same prefix (in the example it is "Transactions"). It will make your life much easier when you have to configure a cluster in production.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文