Обработка больших сообщений с фрагментацией в Azure Logic Apps
Область применения: Azure Logic Apps (потребление)
Azure Logic Apps имеет разные максимальные ограничения на размер содержимого сообщения, которое активируется и обрабатывается в рабочих процессах приложения логики на основе типа ресурса приложения логики и среды, в которой выполняется рабочий процесс приложения логики. Эти ограничения помогают снизить издержки, которые возникают в результате хранения и обработки больших сообщений. Дополнительные сведения об ограничениях размера сообщений см. в статье Ограничения сообщений в Azure Logic Apps.
Если вы используете встроенные действия HTTP или определенные действия управляемого соединителя и вам требуется Azure Logic Apps для работы с сообщениями, превышающими ограничения по умолчанию, можно включить фрагментацию, которая разбивает большое сообщение на меньшие фрагменты. Таким образом вы сможете передавать большие файлы, но при этом действуют определенные условия. Фактически при использовании этих встроенных действий HTTP или определенных действий управляемого соединителя фрагментация является единственным способом, с помощью которого Azure Logic Apps может использовать большие сообщения. Это требование означает, что основной обмен HTTP-сообщениями между Azure Logic Apps и другими службами должен использовать фрагментацию или соединения, созданные управляемыми соединителями, которые вы хотите использовать, также должны поддерживать фрагментацию.
Примечание
Azure Logic Apps не поддерживает фрагментацию триггеров из-за увеличенных издержек при обмене несколькими сообщениями. Кроме того, Azure Logic Apps реализует фрагментацию для действий HTTP с помощью собственного протокола, как описано в этой статье. Поэтому даже если веб-сайт или веб-служба поддерживает фрагментацию, они не будут работать с фрагментацией действий HTTP. Для использования фрагментации действий HTTP с веб-сайтом или веб-службой необходимо реализовать тот же протокол, который используется Azure Logic Apps. В противном случае не включайте фрагментацию в действии HTTP.
В этой статье приводятся общие сведения о фрагментации в Azure Logic Apps и ее настройке для поддерживаемых действий.
Какое сообщение является большим?
Сообщения считаются большими в зависимости от требований службы, которая их обрабатывает. Точное ограничение размера больших сообщений отличается в Logic Apps и соединителях. И Logic Apps, и соединители не могут принимать большие сообщения напрямую, а только с применением фрагментации. Максимальный размер сообщения в Logic Apps см. в статье Ограничения и сведения о конфигурации для Azure Logic Apps. Сведения об ограничении размера сообщений для каждого соединителя см. в справочной документации по соединителю.
Обработка фрагментированного сообщения для Logic Apps
Logic Apps не может напрямую использовать выходные данные из фрагментированных сообщений, размер которых превышает ограничение. Содержимое сообщения в таких выходных данных может быть обработано только теми действиями, которые поддерживают фрагментацию. Действие, которое обрабатывает большие сообщения, должно соответствовать одному из следующих критериев:
- изначально поддерживать фрагментацию, если это действие относится к контейнеру;
- иметь включенную поддержку фрагментации в конфигурации запуска.
В противном случае при попытке получить доступ к выходным данных большого содержимого возникнет ошибка среды выполнения. Сведения о включении фрагментации см. в разделе Настройка фрагментации по протоколу HTTP.
Обработка фрагментированного сообщения для соединителей
Службы, которые взаимодействуют с Logic Apps, могут иметь собственные ограничения на размер сообщения. Эти ограничения часто меньше, чем ограничения Logic Apps. Например, соединитель, поддерживающий фрагментацию, может рассматривать сообщение размером 30 МБ как большое, в то время как Logic Apps — нет. Чтобы соблюсти это ограничение соединителя, Logic Apps разбивает любое сообщение размером свыше 30 МБ на небольшие блоки.
В соединителях, которые поддерживают фрагментацию, базовый протокол фрагментации невидим для пользователей. Однако не все соединители поддерживают фрагментацию, и если размер входящих сообщений превышает ограничения в таком соединителе, возникнет ошибка среды выполнения.
Для действий, которые поддерживают и используют фрагментацию, вы не можете использовать тела, переменные и выражения триггера, например @triggerBody()?['Content']
, так как любой из этих элементов входных данных блокирует операцию фрагментации. Вместо этого примените действие Compose. В частности, создайте поле body
с помощью действия Compose, чтобы сохранять выходные данные тела, переменные и выражения триггера, например так:
"Compose": {
"inputs": {
"body": "@variables('myVar1')"
},
"runAfter": {
"Until": [
"Succeeded"
]
},
"type": "Compose"
},
Чтобы указать ссылку на эти данные в действии фрагментирования, используйте @body('Compose')
.
"Create_file": {
"inputs": {
"body": "@body('Compose')",
"headers": {
"ReadFileMetadataFromServer": true
},
"host": {
"connection": {
"name": "@parameters('$connections')['sftpwithssh_1']['connectionId']"
}
},
"method": "post",
"path": "/datasets/default/files",
"queries": {
"folderPath": "/c:/test1/test1sub",
"name": "tt.txt",
"queryParametersSingleEncoded": true
}
},
"runAfter": {
"Compose": [
"Succeeded"
]
},
"runtimeConfiguration": {
"contentTransfer": {
"transferMode": "Chunked"
}
},
"type": "ApiConnection"
},
Настройка фрагментации по протоколу HTTP
В общих сценариях с HTTP большие файлы, загружаемые и передаваемые по протоколу HTTP, можно разделить, чтобы позволить приложению логики и конечной точке обмениваться большими сообщениями. Тем не менее сообщения необходимо фрагментировать так, как того ожидает Logic Apps.
Если в конечной точке включена фрагментация для загрузки или передачи, действия HTTP в приложении логики автоматически разбивают большие сообщения на блоки. В противном случае в конечной точке необходимо настроить поддержку фрагментации. Если вы не владеете конечной точкой либо соединителем или у вас нет контроля над ними, возможно, вы не сможете настроить фрагментацию.
Кроме того, если в действии HTTP не включена фрагментация, вам также нужно настроить фрагментацию в свойстве runTimeConfiguration
этого действия.
Это свойство можно задать внутри действия непосредственно в редакторе представления кода, как описано далее, либо в конструкторе Logic Apps, как описано здесь:
В правом верхнем углу в окне действия HTTP нажмите кнопку с многоточием ( ... ), а затем выберите Параметры.
В разделе Передача содержимого переведите переключатель Разрешить фрагментирование в положение Вкл.
Чтобы настроить фрагментацию для загрузки или передачи, перейдите к следующим разделам.
Загрузка содержимого блоками
Много конечных точек автоматически отправляют большие сообщения блоками при загрузке с помощью HTTP-запроса GET. Для загрузки фрагментированных сообщений из конечной точки по протоколу HTTP конечная точка должна поддерживать запросы частичного содержимого или поблочную загрузку. Если приложение логики отправляет в конечную точку HTTP-запрос GET для загрузки содержимого и конечная точка отвечает с кодом состояния "206", в ответе содержится фрагментированное содержимое. Logic Apps не может контролировать то, поддерживает ли конечная точка частичные запросы. Тем не менее, когда приложение логики получает первый ответ с кодом "206", оно автоматически отправляет несколько запросов, чтобы загрузить все содержимое.
Чтобы проверить, поддерживает ли конечная точка частичное содержимое, отправьте запрос HEAD. Этот запрос позволяет определить, содержит ли ответ заголовок Accept-Ranges
.
Таким образом, если конечная точка поддерживает поблочную загрузку, но не отправляет фрагментированное содержимое, вы можете настроить это, задав заголовок Range
в HTTP-запросе GET.
Далее подробно описан процесс, который Logic Apps использует для загрузки фрагментированного содержимого из конечной точки в приложение логики.
Ваше приложение логики отправляет HTTP-запрос GET в конечную точку.
При необходимости в заголовке запроса может содержаться поле
Range
, описывающее диапазон байтов для запроса блоков содержимого.Конечная точка возвращает код состояния "206" и основной текст сообщения HTTP.
Сведения о содержимом в этом блоке содержатся в заголовке
Content-Range
ответа, включая информацию о приложении, на основе которой Logic Apps определяет начало и конец блока данных, а также общий размер всего содержимого до фрагментации.Приложение логики автоматически отправляет последующие HTTP-запросы GET.
Они отправляются, пока не будет получено все содержимое.
В приведенном ниже определении действия показан HTTP-запрос GET, в котором задан заголовок Range
.
Заголовок предполагает, что конечная точка должна возвращать поблочное содержимое:
"getAction": {
"inputs": {
"headers": {
"Range": "bytes=0-1023"
},
"method": "GET",
"uri": "http://myAPIendpoint/api/downloadContent"
},
"runAfter": {},
"type": "Http"
}
Запрос GET устанавливает заголовок "Range" со значением "bytes=0-1023", что представляет собой диапазон байтов. Если конечная точка поддерживает запросы частичного содержимого, она возвращает блок содержимого из запрошенного диапазона. Точный формат поля заголовка "Range" может отличаться в зависимости от конечной точки.
Передача содержимого блоками
Чтобы отправить фрагментированное содержимое из действия HTTP, в действии должна быть включена поддержка фрагментации с помощью свойства runtimeConfiguration
.
Это свойство позволяет действию использовать протокол фрагментации.
После этого приложение логики может отправлять начальное сообщение POST или PUT в целевую конечную точку.
Когда конечная точка вернет в ответе предлагаемый размер блока, приложение логики начнет отправлять HTTP-запросы PATCH, содержащие блоки содержимого.
Далее подробно описаны этапы процесса, который Logic Apps использует для передачи фрагментированного содержимого из приложения логики в конечную точку.
Приложение логики отправляет начальный HTTP-запрос POST или PUT с пустым сообщением. Заголовок запроса содержит такие сведения о содержимом, которое приложение логики хочет передать поблочно:
Поле заголовка запроса Logic Apps Значение Тип Описание x-ms-transfer-mode chunked Строка Указывает, что содержимое передается блоками x-ms-content-length < длина_содержимого> Целое число Размер всего содержимого (в байтах) перед фрагментацией Конечная точка возвращает ответ с кодом состояния "200" и такую следующую информацию:
Поле заголовка ответа конечной точки Тип Обязательно Описание Расположение Строка Да URL-адрес расположения для отправки сообщений HTTP PATCH x-ms-chunk-size Целое число Нет Предлагаемый размер блока в байтах Приложение логики создает и отправляет последующие сообщения HTTP PATCH со следующими сведениями:
Блок содержимого с размером, указанным в поле x-ms-chunk-size, или некоторым внутренне вычисленным размером. Блоки отправляются, пока все содержимое, вместе равное x-ms-content-length, не будет последовательно передано.
Следующие сведения заголовка о блоке содержимого отправляются в каждом сообщении PATCH:
Поле заголовка запроса Logic Apps Значение Тип Описание Content-Range < диапазон> Строка Диапазон байтов для текущего блока содержимого, включая начальное значение, конечное значение и общий размер содержимого, например "bytes=0-1023/10100" Content-Type < тип_содержимого> Строка Тип фрагментированного содержимого Content-Length < длина_содержимого> Строка Длина размера в байтах для текущего блока
После каждого запроса PATCH конечная точка подтверждает получение каждого блока, отправляя ответ с кодом состояния "200" и следующими заголовками ответа:
Поле заголовка ответа конечной точки Тип Обязательно Описание Range Строка Да Диапазон байтов для содержимого, полученного конечной точкой, например: "bytes = 0-1023" x-ms-chunk-size Целое число Нет Предлагаемый размер блока в байтах
Например, в этом определении действия показан HTTP-запрос POST на передачу фрагментированного содержимого в конечную точку. В свойстве runTimeConfiguration
действия содержится свойство contentTransfer
, в котором для transferMode
задано значение chunked
:
"postAction": {
"runtimeConfiguration": {
"contentTransfer": {
"transferMode": "chunked"
}
},
"inputs": {
"method": "POST",
"uri": "http://myAPIendpoint/api/action",
"body": "@body('getAction')"
},
"runAfter": {
"getAction": ["Succeeded"]
},
"type": "Http"
}