Можно ли отложить повторную попытку сообщения служебной шины в функции Azure?

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

  • Поймать исключение, заснуть, а затем бросить. Это ужасное решение, так как с меня будет взиматься плата за использование процессора, пока он спит, и это повлияет на пропускную способность функции.
  • Перехватите исключение, клонируйте сообщение, установите свойство ScheduledEnqueueTimeUtc и добавьте его обратно в очередь. Это более приятный способ, но он сбрасывает счетчик доставки, поэтому реальная проблема никогда не будет недоставлена, и она повторно отправляется всем подпискам, если только один подписчик не смог ее обработать.
  • Перехватите исключение и вместо этого поместите сообщение в очередь хранилища. Это означает поддержание очереди хранилища для соответствия каждой подписке и наличие двух функций вместо одной.

В идеале я хотел бы перехватить исключение и выйти из функции, не снимая блокировку сообщения. Таким образом, как только срок действия блокировки истечет, сообщение будет отправлено снова. Однако кажется, что после успешного завершения функция вызывает Complete() для сообщения, а после создания исключения функция вызывает Abandon() для сообщения. Можно ли обойти это или добиться задержки каким-то другим способом?


person Andrew Williamson    schedule 17.04.2018    source источник
comment
Если эти исключения случаются не слишком часто, вы можете создать функцию с таймером, который будет срабатывать только каждые 15 минут и проверять очередь недоставленных сообщений.   -  person JTaub    schedule 18.04.2018


Ответы (3)


Я решу вашу проблему, предложив, чтобы поток, который вы предлагаете, лучше обрабатывался LogicApp по сравнению с чистой функцией.

Реализовать шаблон wait/retry/dequeue next в LogicApp довольно легко, поскольку именно для этого типа управления потоком и был разработан LogicApps.

person Johns-305    schedule 18.04.2018
comment
Да, это определенно больше похоже на то, что мне нужно, учитывая, что у них есть действие HTTP, которое позволяет вам определить политику повторных попыток для кодов возврата 408, 429 и 5XX. Теперь мне нужно выяснить, как извлечь части полученного через посредника сообщения для заголовка авторизации и тела сообщения. - person Andrew Williamson; 18.04.2018

Хотя это все еще находится в предварительной версии (не рекомендуется для производственного кода), вы можете использовать Постоянные функции. Если вы хотите сохранить возможность манипулировать объектами в коде, это, вероятно, ваш лучший выбор!

(+1 к решению LogicApp!)

person Marie Hoeger    schedule 18.04.2018

Теперь это изначально поддерживается через политики повторных попыток, которые были добавлены в Функции Azure примерно в ноябре 2020 года (предварительная версия). Вы можете настроить политику повтора как фиксированную задержку или экспоненциальную отсрочку.

[FunctionName("MyFunction")]
[FixedDelayRetry(10, "00:15:00")]   // retries with a 15-minute delay
public static void Run(
    [ServiceBusTrigger("MyTopic", "MySubscription", Connection = "ServiceBusConnection")] string myQueueItem) 
{
    // Forward message to HTTP endpoint, throwing exception if endpoint unavailable
}
person Douglas    schedule 21.05.2021