Решение проблем регулирования (429 — Слишком много запросов) в Azure Logic Apps

Область применения: Azure Logic Apps (Потребление + Стандартный)

Если рабочий процесс приложения логики испытывает регулирование, которое происходит, когда количество запросов превышает скорость, с которой назначение может обрабатывать в течение определенного периода времени, вы получите ошибку "HTTP 429 Слишком много запросов". Регулирование может привести к таким проблемам, как отложенная обработка данных, снижение быстродействия и появление ошибок, например превышение заданной политики повторов.

Например, следующее действие SQL Server в рабочем процессе потребления показывает ошибку 429, которая сообщает о проблеме регулирования:

Снимок экрана: рабочий процесс потребления с действием SQL Server с ошибкой 429.

В следующих разделах описаны распространенные уровни регулирования рабочего процесса.

Регулирование ресурсов приложения логики

Azure Logic Apps имеет собственные ограничения пропускной способности. Если ресурс приложения логики превышает эти ограничения, ресурс приложения логики регулируется, а не только для конкретного экземпляра рабочего процесса или запуска.

Чтобы найти события регулирования на этом уровне, выполните следующие действия.

  1. Откройте ресурс приложения логики на портале Azure.

  2. В меню ресурсов приложения логики в разделе Мониторинг выберите Метрики.

  3. В разделе Название диаграммы выберите Добавить метрику, чтобы добавить еще одну полосу метрик на диаграмму.

  4. На первой панели метрик в списке Метрика выберите Действие Регулируемые события. В списке Агрегирование выберите Счетчик.

  5. На второй панели метрик в списке Метрика выберите Активировать регулируемые события. В списке Агрегирование выберите Счетчик.

На диаграмме теперь показаны регулируемые события как для действий, так и для триггеров в рабочем процессе приложения логики. Дополнительные сведения см. в статье Просмотр метрик работоспособности и производительности рабочих процессов в Azure Logic Apps.

Для обработки регулирования на этом уровне доступны следующие варианты.

  • Ограничьте количество экземпляров рабочих процессов, которые могут выполняться одновременно.

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

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

  • Включение высокой пропускной способности.

  • Отключение дескрипирования массива или поведения "Разделить в" в триггерах.

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

    Чтобы управлять регулированием, отключите поведение триггера Split On и предоставьте рабочему процессу обработать весь массив одним вызовом, а не обрабатывать один элемент за вызов.

  • Рефакторинг действий в несколько небольших рабочих процессов.

    Как упоминалось ранее, рабочий процесс приложения логики "Потребление" ограничен количеством действий по умолчанию, которые могут выполняться в течение 5 минут. Хотя это ограничение можно увеличить, включив режим высокой пропускной способности, можно также рассмотреть вопрос о том, следует ли разбить действия рабочего процесса на небольшие рабочие процессы, чтобы количество действий, выполняемых в каждом рабочем процессе, оставалось не ниже ограничения. Таким образом, вы уменьшите нагрузку на один рабочий процесс и распределите нагрузку между несколькими рабочими процессами. Такое решение лучше подойдет для действий, которые обрабатывают большие наборы данных или запускаются для параллельного выполнения множества действий, итераций или действия в каждой итерации цикла, число которых превышает предел выполнения действия.

    Например, следующий рабочий процесс потребления выполняет всю работу по получению таблиц из базы данных SQL Server и получению строк из каждой таблицы. Цикл for each параллельно проходит по каждой из таблиц, чтобы действие Получить строки возвращало строки для каждой таблицы. В зависимости от объема данных в таблицах такие действия могут превысить ограничение на количество выполнений.

    Снимок экрана: рабочий процесс потребления

    После рефакторинга исходный рабочий процесс разбивается на родительский и дочерний.

    Следующий родительский рабочий процесс получает таблицы из SQL Server, а затем вызывает дочерний рабочий процесс для каждой таблицы, чтобы получить строки:

    Снимок экрана: родительский рабочий процесс потребления, который получает SQL Server таблицы и вызывает дочерний рабочий процесс.

    Следующий дочерний рабочий процесс вызывается родительским рабочим процессом для получения строк для каждой таблицы:

    Снимок экрана: дочерний рабочий процесс потребления, который получает строки для каждой таблицы.

Регулирование соединителя

Каждый соединитель имеет собственные ограничения регулирования, которые можно найти на странице технического справочника по каждому соединителю. Например, соединитель служебной шины Azure имеет ограничение регулирования до 6000 вызовов в минуту, в то время как соединитель SQL Server имеет ограничения регулирования, которые зависят от типа операции.

Некоторые триггеры и действия, например HTTP, имеют Политику повторов, которую можно настроить в зависимости от Ограничений политики повтора, чтобы реализовать обработку исключений. Политика повторов указывает, каким образом и как часто действие или триггер повторяет запрос после истечения времени ожидания первоначального запроса, либо запрос завершается ошибкой, т. е. выдается ответ 408, 429 или 5xx. Таким образом, когда регулирование запускается и возвращает ошибку 429, Logic Apps использует политику повтора, там где она поддерживается.

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

В следующем примере рабочего процесса потребления показано, где можно найти эти сведения для действия HTTP:

Снимок экрана: рабочий процесс потребления с журналом выполнения, повторными попытками, входными и выходными данными действия HTTP.

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

Для рабочих процессов приложений логики потребления в мультитенантном Azure Logic Apps регулирование выполняется на уровне подключения . Для рабочих процессов приложений логики, которые выполняются в среде службы интеграции (ISE), регулирование по-прежнему выполняется для подключений, отличных от ISE, так как они выполняются в мультитенантной службе Azure Logic Apps. Но подключения ISE, созданные с помощью соединителей ISE, не регулируются, так как они выполняются в интегрированной среде сценариев.

Для обработки регулирования на этом уровне доступны следующие варианты.

  • Настройте несколько подключений для одного действия, чтобы рабочий процесс смог секционирования данных для обработки.

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

    Например, предположим, что рабочий процесс получает таблицы из базы данных SQL Server, а затем получает строки из каждой таблицы. В зависимости от количества строк, которые необходимо обработать, можно использовать несколько соединений и несколько циклов for each, чтобы разделить общее количество строк на меньшие наборы для обработки. В этом сценарии используется два цикла for each для разделения общего количества строк пополам. Первый цикл for each использует выражение, которое получает первую половину. В другом цикле for each используется второе выражение, которое получает вторую половину. Например:

    • Выражение 1. Функция take() возвращает первую часть коллекции. Дополнительные сведения см. по функции take().

      @take(collection-or-array-name, div(length(collection-or-array-name), 2))

    • Выражение 2. Функция skip() удаляет начало коллекции и возвращает все остальные элементы. Дополнительные сведения см. по функции skip().

      @skip(collection-or-array-name, div(length(collection-or-array-name), 2))

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

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

  • Для каждого действия настраивайте собственное соединение.

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

    Например, предположим, что рабочий процесс получает таблицы из базы данных SQL Server и получает каждую строку в каждой таблице. Можно разделить соединения так, чтобы для получения таблиц использовалось одно соединение, а для получения строк использовалось другое.

    В следующем примере показан рабочий процесс потребления, который создает и использует разные подключения для каждого действия:

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

  • Измените параллелизм в цикле "for each".

    По умолчанию итерации цикла "for each" запускаются одновременно до достижения предела по умолчанию. Если у вас есть подключение, которое регулируется внутри цикла "Для каждого", можно уменьшить количество итераций цикла, которые выполняются параллельно. Дополнительные сведения см. в следующей документации:

Служба или система назначения

Хотя соединитель имеет собственные ограничения регулирования, целевая служба или система, вызванная соединителем, может также иметь ограничения регулирования. Например, некоторые API в Microsoft Exchange Server имеют более широкие ограничения регулирования, чем соединитель Office 365 Outlook.

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

Предположим, имеется массив, содержащий 100 элементов. Цикл For each используется для итерации массива и включения управления параллелизмом цикла, чтобы ограничить число параллельных итераций до 20 или текущего ограничения по умолчанию. Внутри этого цикла действие вставляет элемент из массива в базу данных SQL Server, которая разрешает всего 15 вызовов в секунду. Этот сценарий приводит к проблеме с регулированием, так как создается невыполненная работа повторных попыток и никогда не выполняется.

В следующей таблице описана временная шкала того, что происходит в цикле, когда интервал повтора действия составляет 1 секунду.

На момент времени Количество выполненных действий Количество невыполненных действий Количество повторных попыток
T + 0 секунд 20 вставок 5 ошибок, из-за ограничения SQL 5 повторов
T + 0,5 секунд 15 вставок, из-за предыдущих 5 попыток в ожидании Все 15 завершатся ошибкой из-за того, что предыдущее ограничение SQL действует еще 0,5 секунды 20 повторов
(5 предыдущих + 15 новых)
T + 1 секунда 20 вставок 5 ошибок плюс предыдущих 20 повторов, из-за ограничения SQL 25 повторов (20 предыдущих + 5 новых)

Для обработки регулирования на этом уровне доступны следующие варианты.

  • Создайте отдельные рабочие процессы, чтобы каждый из них обрабатывал одну операцию.

    • Продолжая работу с примером сценария SQL Server в этом разделе, можно создать рабочий процесс, который помещает элементы массива в очередь, например очередь Служебная шина Azure. Затем создается другой рабочий процесс, который выполняет только операцию вставки для каждого элемента в этой очереди. Таким образом, только один экземпляр рабочего процесса запускается в определенный момент времени, который либо завершает операцию вставки и переходит к следующему элементу в очереди, либо экземпляр получает 429 ошибок, но не пытается выполнить непродуктивные повторные попытки.

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

      Например, предположим, что у вас есть два рабочих процесса, каждый из которых имеет триггер опроса, который каждую минуту проверяет учетную запись электронной почты на определенную тему, например "Успешно" или "Сбой". Такая установка производит 120 обращений в час. Вместо этого, если вы создаете один родительский рабочий процесс, который опрашивает каждую минуту, но вызывает дочерний рабочий процесс, который выполняется в зависимости от того, является ли тема "Успешно" или "Сбой", вы сократите число проверок опроса до половины или 60 в этом случае.

  • Настройка пакетной обработки. (Только рабочие процессы потребления)

    Если целевая служба поддерживает пакетные операции, то регулирование можно устранить за счет обработки элементов группами или пакетами. Чтобы реализовать решение пакетной обработки, создайте рабочий процесс приложения логики "получатель пакета" и рабочий процесс приложения логики "отправитель пакета". Пакет отправителя собирает сообщения или элементы до тех пор, пока не будут выполнены указанные условия, а затем отправляет эти сообщения или элементы одной группой. Получатель пакета принимает эту группу и обрабатывает содержащиеся в ней сообщения или элементы. Дополнительные сведения см. в разделе Пакетная обработка сообщений в группах.

  • Используйте версии веб-перехватчика для триггеров и действий, а не опрашивающие версии.

    Почему? Опрашивающий триггер продолжает проверять целевую службу или систему через определенные интервалы времени. Очень часто такой интервал, например раз в секунду, может приводить к проблемам регулирования. Однако триггер или действие веб-перехватчика, например HTTP, создает только один вызов целевой службы или системы, который происходит во время подписки и запрашивает, что назначение уведомляет триггер или действие только при наступлении события. Таким образом, триггеру или действию не нужно постоянно проверять назначение.

    Таким образом, если целевая служба или система поддерживает веб-перехватчики или имеет соединитель с версией веб-перехватчика, то этот вариант является более предпочтительным, чем использование опрашивающей версии. Чтобы определить триггеры и действия веб-перехватчика, убедитесь, что они имеют тип ApiConnectionWebhook или не требуют указания периодичности. Дополнительные сведения см. в статьях Триггер APIConnectionWebhook и Действие APIConnectionWebhook.

Дальнейшие действия