Обзор мертвых очередей шины служебная шина

Очереди служебной шины Azure и подписки на разделы предоставляют дополнительную очередь, которая называется очередью недоставленных сообщений. Очередь недоставленных сообщений не требуется создавать явным образом, и ее нельзя удалить или администрировать отдельно от основной сущности.

В этой статье описываются очереди недоставленных сообщений в служебная шина. Большую часть обсуждения иллюстрирует пример Dead-Letter queues на сайте GitHub.

Очередь недоставленных сообщений

Очередь недоставленных сообщений предназначена для хранения сообщений, которые невозможно доставить ни одному адресату либо не удалось обработать. Сообщения из очереди DLQ можно извлечь и проверить. Приложение может разрешить пользователю исправлять проблемы и повторно отправить сообщение.

С точки зрения интерфейса API и протокола очередь DLQ очень похожа на другие очереди за исключением того, что сообщения могут отправляться только посредством операции недоставленного сообщения родительской сущности. Кроме того, не учитывается время жизни, и нельзя отправить сообщение в очередь мертвых писем. Очередь недоставленных сообщений полностью поддерживает обычные операции, такие как доставка с предварительным просмотром и блокировкой, получение и удаление, а также транзакционные операции.

Автоматическая очистка очереди DLQ не выполняется. Сообщения остаются в очереди непринятых сообщений (DLQ), пока вы явно не извлечете их оттуда и не удалите или обработаете недоставленное сообщение.

Путь к очереди недоставленных сообщений

Каждая очередь и каждая подписка имеют собственную подочередь недоставленных сообщений. Вы можете обратиться к нему напрямую с помощью следующего синтаксиса (используется в Azure CLI, REST и таких средствах, как обозреватель служебная шина):

<queue path>/$deadletterqueue
<topic path>/Subscriptions/<subscription path>/$deadletterqueue

При использовании библиотеки Azure.Messaging.ServiceBus .NET вы не создаете этот путь самостоятельно. Вместо этого задайте значение ServiceBusReceiverOptions.SubQueueSubQueue.DeadLetter при создании приемника. Пример см. в разделе "Получение сообщений из очереди недоставленных писем".

Путь к очереди передачи недоставленных писем

Если сообщение не может быть переслано в место назначения в сценариях автоматической пересылки или send via, оно помещается в очередь недоставленных сообщений передачи (TDLQ) исходного объекта, который выполнял пересылку, а не в целевой объект. Каждая очередь или подписка, пересылающая сообщения, имеет собственную подочередь передачи недоставленных сообщений, к которой можно обращаться напрямую, используя следующий синтаксис:

<queue path>/$Transfer/$DeadLetterQueue
<topic path>/Subscriptions/<subscription path>/$Transfer/$DeadLetterQueue

При использовании библиотеки .NET Azure.Messaging.ServiceBus задайте для ServiceBusReceiverOptions.SubQueue значение SubQueue.TransferDeadLetter. Пример см. в разделе "Получение сообщений из очереди недоставленных сообщений".

Количество сообщений в очереди недоставленных сообщений

Получение количества сообщений в очереди недоставленных писем на уровне раздела неприменимо, так как сообщения не сидят на уровне раздела. Вместо этого, когда отправитель отправляет сообщение в раздел, оно за несколько миллисекунд передается в подписку этого раздела и уже не находится на уровне раздела. Сообщения можно увидеть в DLQ, связанной с подпиской на тему. В следующем примере служебная шина Explorer показывает, что в настоящее время в DLQ для подписки test1 находятся 62 сообщения.

62 сообщения в очереди недоставленных писем для подписки test1.

Вы также можете получить количество сообщений DLQ с помощью команды az servicebus topic subscription showAzure CLI.

Перемещение сообщений в очередь недоставленных писем (DLQ)

В служебной шине есть несколько действий, которые приводят к отправке сообщений в очередь DLQ из самой системы обработки сообщений. Сообщения также могут явно перемещаться в очередь DLQ самим приложением. К недоставленным сообщениям добавляются следующие два свойства (причина и описание недоставленных сообщений). Приложения могут определять собственные коды для свойства причины недоставленных сообщений, однако система задает следующие значения.

Причина недоставленных сообщений. Описание ошибки обработки недоставленных сообщений.
HeaderSizeExceeded Квота на размер этого потока превышена.
TTLExpiredException Срок действия сообщения истёк, и оно было перемещено в очередь недоставленных сообщений. Дополнительные сведения см. в разделе Срок жизни.
Session ID is null Сущность, поддерживающая сеансы, не допускает использование сообщений, идентификатор сеанса которых имеет значение null.
MaxTransferHopCountExceeded Максимальное количество разрешенных переходов при переадресации между очередями превысило установленный предел. Задано значение 4.
MaxDeliveryCountExceeded Сообщение не удалось обработать после максимального количества попыток доставки. Дополнительные сведения см. в разделе Максимальное число доставок.

Срок жизни

При включении функции мертвых писем для очередей или подписок все сообщения с истекшим сроком действия перемещаются в очередь мертвых писем (DLQ). Код причины недоставленной буквы имеет значение TTLExpiredException. Отложенные сообщения не будут удалены и перемещены в очередь недоставленных писем после истечения срока их действия. Такое поведение предусмотрено программой.

Максимальное число доставок

Количество попыток доставки сообщений для очередей и подписок служебная шина ограничено. Значение по умолчанию — 10. Всякий раз, когда сообщение доставлено под блокировкой для просмотра, но либо явно отменено, либо срок действия блокировки истек, число доставки сообщения увеличивается. Если число доставок превышает это ограничение, сообщение перемещается в очередь DLQ. Причина помещения сообщения в DLQ задана как MaxDeliveryCountExceeded. Это поведение нельзя отключить, но можно увеличить максимальное число попыток.

Ошибки при обработке правил подписки

Если включить механизм обработки неподтверждённых сообщений для исключений при фильтрации, то все ошибки, возникающие во время выполнения правила фильтра SQL для подписки, попадают в очередь недоставленных писем (DLQ) вместе с проблемным сообщением. Не используйте этот параметр в рабочей среде, в которой есть типы сообщений, отправляемые в раздел, у которых нет подписчиков, так как это может привести к большой нагрузке сообщений DLLQ. Таким образом, убедитесь, что все сообщения, отправленные в раздел, имеют по крайней мере одну соответствующую подписку.

Обработка недоставленных сообщений на уровне приложения

Помимо системных функций работы с недоставленными сообщениями, приложения могут использовать очередь DLQ (очередь неприемлемых сообщений) для явного отклонения недопустимых сообщений. Недопустимые сообщения могут включать сообщения, которые невозможно должным образом обработать из-за какого-либо системного сбоя, сообщения с некорректной полезной нагрузкой или сообщения, которые не проходят проверку подлинности при использовании какой-либо схемы безопасности на уровне сообщений.

В .NET вызовите метод ServiceBusReceiver.DeadLetterMessageAsync.

Рекомендуется указать тип исключения в DeadLetterReason и трассировку стека исключения в DeadLetterDescription, так как это упрощает устранение причины проблемы, приводящей к отправке сообщений в мертвую очередь. Это может привести к тому, что некоторые сообщения превышают ограничение квоты на 256 КБ для уровня "Стандартный" Служебная шина Azure. Вы можете обновить пространство имен служебная шина с уровня 'Стандартный' до уровня 'Премиум', чтобы иметь большие квоты и лимиты.

Получение сообщений из очереди недоставленных писем

Чтобы получить сообщение из очереди недоставленных сообщений с помощью библиотеки Azure.Messaging.ServiceBus .NET, задайте для ServiceBusReceiverOptions.SubQueue значение SubQueue.DeadLetter при создании получателя. Библиотека выполняет адресацию подочереди недоставленных сообщений за вас.

using Azure.Identity;
using Azure.Messaging.ServiceBus;

string fullyQualifiedNamespace = "<NAMESPACE-NAME>.servicebus.windows.net";
string queueName = "<QUEUE-NAME>";

// 1. Create the top-level client. Passwordless authentication is recommended.
await using var client = new ServiceBusClient(fullyQualifiedNamespace, new DefaultAzureCredential());

// 2. Configure options to target the dead-letter sub-queue.
var options = new ServiceBusReceiverOptions
{
    SubQueue = SubQueue.DeadLetter
};

// 3. Create a receiver scoped to the dead-letter queue. For a subscription's
//    dead-letter queue, use: client.CreateReceiver(topicName, subscriptionName, options).
ServiceBusReceiver dlqReceiver = client.CreateReceiver(queueName, options);

// 4. Receive a dead-lettered message.
ServiceBusReceivedMessage dlqMessage = await dlqReceiver.ReceiveMessageAsync();

// 5. Inspect why the message was dead-lettered.
string reason = dlqMessage.DeadLetterReason;
string description = dlqMessage.DeadLetterErrorDescription;

// 6. Complete the message to remove it from the dead-letter queue.
await dlqReceiver.CompleteMessageAsync(dlqMessage);

Тот же шаблон работает для очереди недоставленных писем с помощью SubQueue.TransferDeadLetter. Полный пример см. в статье "Получение сообщений из очереди недоставленных сообщений".

Обработка недоставленных писем в сценариях автоматической пересылки

Сообщения отправляются в очередь недоставленных писем в следующих условиях:

  • Сообщение проходит более 4 очередей или разделов, которые связаны друг с другом.
  • Целевая очередь (или раздел) отключена или удалена.
  • Очередь или тема назначения превышает максимальный размер объекта.

Обработка невостребованных сообщений в сценариях отправки

  • Если очередь или раздел назначения отключены, сообщение отправляется в очередь недоставленных сообщений (TDLQ) исходной очереди.
  • Если целевая очередь или сущность превышают размер сущности, сообщение отправляется в TDLQ исходной очереди.

Вы можете проверить, сколько сообщений ожидается в очереди недоставленных сообщений, прочитав TransferDeadLetterMessageCount свойство среды выполнения исходной сущности. Дополнительные сведения см. в разделе "Количество сообщений".

Получение сообщений из очереди недоставленных сообщений

Очередь передачи недоставленных сообщений — это подочередь исходной сущности, поэтому сообщения из неё получают так же, как и из обычной очереди недоставленных сообщений: настройте получатель на исходную очередь (или подписку исходного раздела) и выберите подочередь передачи недоставленных сообщений.

При использовании библиотеки Azure.Messaging.ServiceBus .NET задайте значение ServiceBusReceiverOptions.SubQueueSubQueue.TransferDeadLetter при создании приемника. Библиотека обрабатывает подочередь недоставленных сообщений передачи за вас.

using Azure.Identity;
using Azure.Messaging.ServiceBus;

string fullyQualifiedNamespace = "<NAMESPACE-NAME>.servicebus.windows.net";

// The source queue that forwards messages. The transfer dead-letter queue
// lives on this entity, not on the destination.
string sourceQueueName = "<SOURCE-QUEUE-NAME>";

// 1. Create the top-level client. Passwordless authentication is recommended.
await using var client = new ServiceBusClient(fullyQualifiedNamespace, new DefaultAzureCredential());

// 2. Configure options to target the transfer dead-letter sub-queue.
var options = new ServiceBusReceiverOptions
{
    SubQueue = SubQueue.TransferDeadLetter
};

// 3. Create a receiver scoped to the source entity's transfer dead-letter queue.
//    For a subscription that forwards, use:
//    client.CreateReceiver(topicName, subscriptionName, options).
ServiceBusReceiver tdlqReceiver = client.CreateReceiver(sourceQueueName, options);

// 4. Receive a message that failed to transfer to its destination.
ServiceBusReceivedMessage tdlqMessage = await tdlqReceiver.ReceiveMessageAsync();

// 5. Inspect why the message couldn't be transferred.
string reason = tdlqMessage.DeadLetterReason;
string description = tdlqMessage.DeadLetterErrorDescription;

// 6. Complete the message to remove it from the transfer dead-letter queue.
await tdlqReceiver.CompleteMessageAsync(tdlqMessage);

Отправка недоставленных сообщений для повторной обработки

После устранения проблемы, вызвавшей недоставленное сообщение, его можно повторно отправить в очередь или раздел для повторной обработки. Самый простой подход — использовать обозреватель служебная шина на портале Azure, который позволяет просматривать сообщения в очереди недоставленных писем, изменять содержимое или свойства при необходимости и повторно отправлять их ( по отдельности или в пакетах). Операторы часто предпочитают этот интерфейс, поскольку он показывает, в сообщениях каких типов произошёл сбой, от каких исходных сущностей они поступили и почему, при этом по-прежнему позволяя повторно отправить пакет сообщений.

См. раздел Включение функции недоставленных сообщений для очереди или подписки, чтобы узнать о различных способах настройки недоставленных сообщений по истечении срока действия.