Задержка повтора функции с триггером очереди Azure ServiceBus

У меня есть функция Azure, которая запускается очередью служебной шины. Если функция завершается сбоем, она немедленно повторяется (через 1 с) до 10 раз. Однако я хотел бы повторять попытку каждые пять минут. Даже после прочтения документации мне было неясно, как это должно быть реализовано.

[Function("Foo")]
public async Task Run(
  ServiceBusTrigger("FooQueue",
  Connection = "ServiceBusConnection")]
  Foo foo,
  int deliveryCount,
  DateTime enqueuedTimeUtc,
  string messageId)

В документации говорится, что поведение повторной попытки можно настроить в файле host.json. Однако там также говорится, что настройки clientRetryOptions применяются только к взаимодействию со службой служебной шины. Они не влияют на повторные попытки выполнения функций.

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

Каков «официальный» способ реализации стратегии повторных попыток? Предполагается ли это реализовать в самой функции, используя задержки типа Task.Delay вместе с параметром DeliveryCount?

Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
Как установить LAMP Stack 1/2 на Azure Linux VM
Как установить LAMP Stack 1/2 на Azure Linux VM
В дополнение к нашему предыдущему сообщению о намерении Azure прекратить поддержку Azure Database для MySQL в качестве единого сервера после 16...
0
0
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Как вы уже узнали, триггер служебной шины может выполнять немедленные повторные попытки только с помощью MaxDeliveryCount. Отложенные повторы не поддерживаются ни пакетом SDK для функций, ни служебной шиной Azure.

Для отложенных повторных попыток с функциями изолированного Worker SDK вы можете реализовать собственное решение, доступное с помощью опции промежуточного программного обеспечения, которую поддерживает новый Functions SDK. Я изложил эту идею в блоге . Версия TLDR предназначена для использования счетчика доставки для немедленных повторных попыток и выдачи клонированного сообщения для отложенных повторных попыток, используя заголовки сообщений для отслеживания повторных попыток.

Эй, спасибо за ваш ответ. Я прочитал ваш пост в блоге. Чтобы разобрать это: - Вы создаете свою собственную очередь ошибок вместо встроенной очереди недоставленных писем, потому что таким образом вы можете сохранить фактическую ошибку (исключение). - Вы реализуете отложенную повторную попытку, используя ScheduleMessageAsync Кстати: в вашем сообщении в блоге было бы полезно включить недостающие методы расширения CloneForError и CreateSenderFor. В остальном отличный пост, еще раз спасибо за помощь.

Andreas F 02.09.2024 10:50

В чем был бы недостаток, если бы я просто добавил Task.Delay(TimeoutAfterError) в блок Catcb самой функции? Я знаю, что у меня все еще будет проблема с общими ошибками в DLQ, но для единственной цели реализации задержки этого будет достаточно, не так ли?

Andreas F 02.09.2024 10:56

Подход с задержкой может привести к тому, что у вас закончится время блокировки, что приведет к повторной доставке сообщения. Допустим, настроена очередь на блокировку на 1 минуту. Вашей функции потребовалось 35 секунд для обработки сообщения, но она не удалась, а отложенная повторная попытка настроена на выполнение через 15 секунд. Выглядит нормально, но это не так. Блокировка сообщения длится 60 секунд, из которых 50 секунд уже были израсходованы, и когда будет выполнена попытка обработки после задержки, сообщение будет разблокировано и обработано другим экземпляром. Вы могли бы пройти до 5 минут блокировки, но она вас догонит.

Sean Feldman 02.09.2024 18:51

Еще одно ограничение, о котором следует помнить, — это время выполнения функции. Если вы придерживаетесь плана потребления, есть жесткая остановка. Одна отложенная повторная попытка может не сработать для всех сценариев, поэтому вам может потребоваться выполнить откат несколько раз и использовать не линейное, а экспоненциальное время. Когда вы проходите через различные сценарии, подход Task.Delay(), хотя и применимый для конкретного сценария, становится неустойчивым во многих других сценариях.

Sean Feldman 02.09.2024 18:53

Ах да, имеет смысл. Большое спасибо за ваше объяснение.

Andreas F 03.09.2024 08:24

Другие вопросы по теме