Как избежать попадания сообщения в очередь `deadletter` служебной шины azure

Я получаю сообщения из темы/подписки служебной шины. ProcessMessage Добавление сообщений в одну ограниченную по емкости очередь (не более 200 сообщений за раз). После обработки одного сообщения я сделал его CompleteAsync, только когда ProcessMessage дает true.

Теперь, если возникает какое-то исключение, скажем, очередь заполнена и не готова принимать новые сообщения, тогда я генерирую исключение, и ProcessMessage дает false. В этом случае _subscriptionClient.CompleteAsync не вызывается, но сообщение помещается в очередь deadletter.

Как предотвратить это? сообщение не должно идти в очередь deadletter и должно подождать какое-то время для обработки?

Примечание. Я добавил логику AbandonAsync в соответствии с предложением комментария, но сообщение по-прежнему попадает в список недоставленных сообщений и больше не появляется в подписке на тему. Пожалуйста, предложите!

Максимальное количество доставок = 5. Попытка была выполнена 5 раз, после чего письмо было перемещено в недоставленные письма.

_subscriptionClient = new SubscriptionClient(connectionString, topicName, subscriptionName);

            _subscriptionClient.RegisterMessageHandler(
                async (message, token) =>
                {
                    if (await ProcessMessage(message, token))
                    {
                        await _subscriptionClient.CompleteAsync(message.SystemProperties.LockToken);
                    }
                    else
                    {
                        await _subscriptionClient.AbandonAsync(message.SystemProperties.LockToken);
                    }
                },
                
                new MessageHandlerOptions(ExceptionReceivedHandler) { MaxConcurrentCalls = 1, AutoComplete = false });


  private async Task<bool> ProcessMessage(Message message, CancellationToken token)
    {
       var processed = false;
       try
        {
           //adding message to queue for further process
           processed = true;
           
        }
        catch
        {
            //in case  queue  is full, generating exception and return false
            processed = false;
        }

        return processed;
    }

person user584018    schedule 15.09.2020    source источник
comment
Вы можете добавить логику для повторной попытки, прежде чем пометить обработку как ложную. Кроме того, вы можете повторно поставить сообщение в ту же очередь, чтобы его можно было выбрать снова.   -  person user1672994    schedule 15.09.2020
comment
Если вы хотите, чтобы сообщение снова появилось в очереди для повторной попытки, вы можете вызывать AbandonAsync до тех пор, пока не превысит максимальное количество доставленных сообщений.   -  person krishg    schedule 15.09.2020
comment
Спасибо @KrishnenduGhosh-MSFT, я попробовал (проверьте мой обновленный код), сообщение все равно перемещается в недоставленное письмо. Не могли бы вы предложить!   -  person user584018    schedule 15.09.2020
comment
@ user1672994, можете ли вы предложить какой-нибудь пример кода?   -  person user584018    schedule 15.09.2020
comment
Максимальное количество доставок = 5, было сделано 5 попыток, затем оно было перемещено в недоставленные письма.   -  person user584018    schedule 15.09.2020


Ответы (1)


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

Всякий раз, когда сообщение было доставлено клиенту, но не было завершено по каким-либо причинам, счетчик доставки будет автоматически увеличен на 1 для этого сообщения. Когда счетчик доставки совпадает со счетчиком MaxDeliveryCount, сообщение автоматически перемещается в очередь недоставленных сообщений.

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

Сказав это, может быть два возможных решения, которые могут точно соответствовать вашим требованиям:

  • Иметь очень большое значение MaxDelivery Count.
  • Использовать сообщения из очереди недоставленных сообщений — повторно отправить данные в очередь — это может оказаться бесполезным в вашем сценарии. но просто хотел добавить это как предложение - на всякий случай.
person Community    schedule 15.09.2020