Отмена функции Azure с помощью триггера очереди без опасной очереди

Мы используем следующую настройку:

Мы используем функцию Azure с триггером очереди для обработки очереди сообщений JSON.

Каждое из этих сообщений просто пересылается в конечную точку API через HTTP POST для дальнейшей обработки.

API может возвращать 3 возможных кода состояния HTTP; 200 (ОК), 400 (неверный запрос), 500 (внутренняя ошибка сервера).

Если API возвращает 200, сообщение было обработано правильно и все в порядке. Кажется, что функция триггера очереди автоматически удаляет сообщение из очереди, и нас это устраивает.

Если API возвращает 400, у API есть логика, которая берет сообщение и добавляет его в таблицу со статусом, указывающим, что оно было искажено или по другим причинам не могло быть обработано. Поэтому нас устраивает автоматическое удаление сообщения из очереди, и функция Azure может нормально завершиться.

Если API возвращает 500, мы гарантируем, что функция повторяет отправку сообщения в API, пока код состояния не станет 200 или 400 (потому что, вероятно, проблема с API, и мы не хотим потерять сообщения). Для этого мы используем Polly. У нас он настроен так, что он, по сути, будет продолжать повторять попытки вечно при экспоненциальной отсрочке.

Однако недавно мы столкнулись с этой проблемой:

Есть определенные ситуации, когда API возвращает 500 для определенных сообщений. Эта ошибка носит временный характер и будет появляться и исчезать непредсказуемо. Повторная попытка с использованием Polly будет прекрасна, за исключением того, что не все сообщения вызывают эту ошибку, и, по сути, «плохие» сообщения блокируют обработку «хороших» сообщений.

Скажем, у меня в очереди 50 сообщений. Первые 32 сообщения в начале очереди являются «плохими» и иногда возвращают 500 из API. Эти сообщения собираются функцией Azure и обрабатываются одновременно. Остальные 18 сообщений являются «хорошими» и вернут 200. Эти «хорошие» сообщения не будут обработаны, пока «плохие» сообщения не будут успешно обработаны. По сути, плохие создают пробки для хороших.

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

Могу ли я добиться этого с помощью функции триггера очереди? Могу ли я сделать это, используя вместо этого триггер таймера?

Спасибо большое!


person David Omid    schedule 13.05.2017    source источник


Ответы (1)


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

Несколько предложений:

  • Выдать ошибку, чтобы использовать подозрительную очередь, и обработать там логику.
  • Отправьте эти сообщения в другую «длительную» очередь по вашему выбору с привязкой вывода.
  • Используйте выходную привязку типа CloudQueue, которая подключается к вашей входной очереди. При обнаружении проблемного сообщения добавьте его в очередь вывода с помощью параметра initialVisibilityDelay, чтобы отправить его в конец очереди: https://docs.microsoft.com/en-us/dotnet/api/microsoft.windowsazure.storage.queue.cloudqueue.addmessage?view=azure-dotnet

Изменить: Вот таблица привязки параметров типы

введите здесь описание изображения

person Matt Mason    schedule 13.05.2017
comment
Спасибо большое! Итак, просто чтобы уточнить, если я выдаю ошибку, чтобы использовать очередь отравлений, мне все равно придется использовать другую функцию для обработки логики и попытаться отправить ее снова? Кроме того, в документации, которую вы связали, не показана возможность использования выходной привязки типа CloudQueue, а только CloudQueueMessage. Могу ли я использовать CloudQueueMessage и просто установить NextVisibleTime или в документации должно быть указано, что я могу использовать CloudQueue? - person David Omid; 14.05.2017
comment
Правильная, опасная очередь потребует, чтобы другая функция запускала опасную очередь. Я считаю, что NextVisibleTime доступен только для чтения, поэтому вам понадобится объект очереди sdk. Отредактировал ответ с помощью шпаргалки типов, которые можно привязать к параметрам - person Matt Mason; 15.05.2017
comment
Отлично, большое спасибо, эта шпаргалка очень полезна! Поэтому я просто указываю имя очереди вывода в файле function.json в качестве привязки вывода, затем добавляю параметр CloudQueue, и аргумент будет иметь значение этой очереди при запуске функции? Могу ли я использовать ту же очередь, что и моя очередь ввода? Я думаю, что если мы увеличим задержку видимости на значительную величину, а затем добавим ее обратно в ту же очередь, это даст функции достаточно времени для обработки других сообщений. - person David Omid; 15.05.2017
comment
Ага, точно. Я не думаю, что вы можете использовать CloudQueue в качестве входа триггера - нам нужно исключить из очереди и взять на себя ответственность за сообщение, которое запускает функцию. Хотя вы можете попробовать. - person Matt Mason; 15.05.2017
comment
Отлично, я добавлю сообщение в ту же очередь, из которой пришло сообщение, и установлю задержку, чтобы оно находилось в конце очереди. Я попробую и посмотрю, есть ли еще проблемы. Большое спасибо! - person David Omid; 15.05.2017