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

        private readonly RetryExponential _retryPolicy = new RetryExponential(
            TimeSpan.FromSeconds(1),
            TimeSpan.FromMinutes(20),
            10);

Когда SQL Server временно не работает ("because its replica role is RESOLVING which does not allow connections. Try the operation again later."), сообщения попадают в очередь недоставленных сообщений без повторных попыток.

Что мне делать, чтобы получить повторные попытки?

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

ОБНОВЛЕНИЕ:

Обсудив с коллегами и немного изучив Application Insights, я вижу, что на самом деле было выполнено 10 повторных попыток, но все в течение 2 секунд. Это максимальное количество доставок, заданное для самой подписки, а не для клиента. На эту доставку не влияет экспоненциальная отсрочка, как я хочу и нуждаюсь.

Max DElivery Count on subscription is 10

3
Alf Kåre Lefdal 10 Окт 2019 в 18:59

1 ответ

Лучший ответ

Я просмотрел исходный код SDK, и кажется, что только временное исключение ServiceBusException дает повторные попытки, но я нахожу это довольно странным.

Это правильно и соответствует дизайну. Если ошибка временная (проблема с подключением, регулирование и т. Д.), Клиент попытается повторить попытку, используя RetryPolicy. В противном случае повторная попытка не поможет, поэтому повторная попытка той же операции не поможет.

В вашем конкретном случае - код, который у вас есть, выполняется, а сообщение обрабатывается. Между клиентом и брокером нет никаких проблем. Вот почему политика не срабатывает. Далее вы подтверждаете, что это проблема приложения, учитывая, что сообщение повторяется вашим процессом и попадает в очередь недоставленных сообщений.

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

Что вам нужно, так это повторные попытки приложения и отсрочка, чтобы гарантировать, что сообщение не будет повторяться сразу несколько раз, что приведет к тому, что оно будет пропущено без букв. Эта часть может быть немного сложнее, в зависимости от того, как долго ваш SQL-сервер не работает. Есть несколько вариантов:

  1. Запланируйте сообщение в будущем, чтобы позволить SQL Server восстановиться. Эта опция потребует запланировать новое сообщение.
  2. Отложите сообщение и обработайте его позже. Это будет означать, что вам нужно будет вести учет отложенных сообщений SequenceNumber s. Один из способов реализовать эту опцию - запланировать новое сообщение с порядковым номером исходного сообщения.
  3. Используйте абстракцию поверх служебной шины, которая предоставляет высокоуровневую концепцию / функцию для выполнения повторных попыток, например MassTransit или NServiceBus (Восстанавливаемость).
1
Sean Feldman 10 Окт 2019 в 16:35