Как отклонить сообщения после переложения из одной очереди в другую?
С Spring и RabbitMQ я установил две тематические биржи x
а также dlx
и две очереди q
а также dlq
, q
связан с x
а также dlq
в dlx
, dlx
настроен как обмен письмами q
,
Когда сообщение в q
отклонено (без очереди) успешно отправлено dlx
а затем dlq
,
Теперь я использую лопатку-плагин, чтобы переместить сообщения с мертвыми буквами в dlq
вернуться к q
, Это работает успешно, пока сообщения успешно обрабатываются на этот раз (подтверждение).
Но если одно из этих совковых сообщений вq
снова отвергается, молча отбрасывается. Я ожидаю, что он будет отправлен в DLX dlx
снова. Я что-то неправильно настроил или неправильно понял концепцию DLX или лопаты?
1 ответ
Я подозреваю, что вы попали на вкус этого...
Можно сформировать цикл сообщения о недоставке. Например, это может произойти, когда очередь сообщений с ошибками отправляется на обмен по умолчанию без указания ключа маршрутизации недоставленных сообщений. Сообщения в таких циклах (то есть сообщения, которые попадают в одну и ту же очередь дважды) будут отбрасываться, если в течение всего цикла не было отклонений.
... потому что ты копаешься Смотрите обмен мертвыми буквами.
Вместо этого настройте DLQ с TTL и конфигурацией недоставленных сообщений, которая приводит к тому, что сообщения с истекшим сроком действия направляются обратно в исходную очередь. Таким образом, x-death
заголовок получает две записи - 1 для отклонений из исходной очереди и 1 для истечения срока из DLQ.
Я предполагаю, что с лопатой брокер думает, что есть цикл.
Я не думаю, что ваша проблема в циклах. Предполагая, что вы используете плагин лопатки из графического интерфейса управления Rabbit, это изменяет ключ маршрутизации для сообщения, чтобы явно использовать ключ маршрутизации очереди на 'Default Exchange'
https://www.rabbitmq.com/tutorials/amqp-concepts.html
Обмен по умолчанию - это прямой обмен без имени (пустая строка), предварительно объявленного брокером. У него есть одно специальное свойство, которое делает его очень полезным для простых приложений: каждая создаваемая очередь автоматически привязывается к ней с помощью ключа маршрутизации, который совпадает с именем очереди.
Основываясь на приведенном выше примере, я предполагаю, что у вас есть следующие настройки:
q
аргументы -x-dead-letter-exchange = dlx
q
привязка:test_message
dlq
привязка:test_message
Итак, если вы отправите сообщение x
с ключом маршрутизации test_message
, вот как он маршрутизируется:
- Появляется в
q
- Потребитель в
q
получает сообщение, отправляет nack, который отправляетdlx
с ключом маршрутизацииtest_message
dlx
имеетdlq
настроен для привязки кtest_message
ключ маршрутизации, поэтому сообщение появляется вdlq
Теперь, когда вы используете плагин лопаты из dlq
переместить все сообщения в q
нравится:
Затем это отправляет сообщение exchange = ''
а также routing_key = 'q'
. Также из https://www.rabbitmq.com/dlx.html говорится:
Если этот параметр не установлен, будут использоваться собственные ключи маршрутизации сообщения.
Итак, вот что происходит:
- Сообщение появляется в
q
сrouting_key = q
- Поскольку нет
x-dead-letter-routing-key
настроен, это мертвые буквы дляdlx
с routing_keyq
- Нет привязки к q в
dlx
, сообщение потеряно
2 возможных исправления:
- Добавить еще одну привязку к
dlq
кrouting_key = q
- Настройте вручную
x-dead-letter-routing-key
наq
очередь, чтобы всегда отправлять на один и тот же ключ маршрутизации в мертвом письме