Поделиться через


Функции HTTP

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

Предоставление API-интерфейсов HTTP

Оркестрации и сущности могут вызываться и управляться с помощью HTTP-запросов. Расширение "Устойчивые функции" предоставляет встроенные API HTTP. Оно также предоставляет интерфейсы API для взаимодействия с оркестрациями и сущностями из функций, активируемых HTTP.

Встроенные API HTTP

Расширение "Устойчивые функции" автоматически добавляет набор API-интерфейсов HTTP к узлу Функций Azure. С помощью этих API-интерфейсов можно взаимодействовать и управлять согласованиями и сущностями без написания кода.

Поддерживаются следующие встроенные API-интерфейсы HTTP.

Полное описание всех встроенных API HTTP, предоставляемых расширением "Устойчивые функции", см. в статье об API-интерфейсах HTTP.

Обнаружение URL-адреса API HTTP

Привязка клиента оркестрации предоставляет API, которые могут создавать удобные полезные данные ответа HTTP. Например, может создаваться ответ, содержащий ссылки на API управления для конкретного экземпляра оркестрации. В следующих примерах показана функция HTTP-триггера, которая демонстрирует использование этого API для нового экземпляра оркестрации.

// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;

namespace VSSample
{
    public static class HttpStart
    {
        [FunctionName("HttpStart")]
        public static async Task<HttpResponseMessage> Run(
            [HttpTrigger(AuthorizationLevel.Function, methods: "post", Route = "orchestrators/{functionName}")] HttpRequestMessage req,
            [DurableClient] IDurableClient starter,
            string functionName,
            ILogger log)
        {
            // Function input comes from the request content.
            object eventData = await req.Content.ReadAsAsync<object>();
            string instanceId = await starter.StartNewAsync(functionName, eventData);

            log.LogInformation($"Started orchestration with ID = '{instanceId}'.");

            return starter.CreateCheckStatusResponse(req, instanceId);
        }
    }
}

Запуск функции оркестратора с помощью функций HTTP-триггеров, показанных выше, можно выполнить с помощью любого клиента HTTP. Следующая команда cURL запускает функцию оркестратора с именем DoWork:

curl -X POST https://localhost:7071/orchestrators/DoWork -H "Content-Length: 0" -i

Далее приведен пример ответа для оркестрации с идентификатором abc123. Некоторые сведения были удалены для ясности.

HTTP/1.1 202 Accepted
Content-Type: application/json; charset=utf-8
Location: http://localhost:7071/runtime/webhooks/durabletask/instances/abc123?code=XXX
Retry-After: 10

{
    "id": "abc123",
    "purgeHistoryDeleteUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/abc123?code=XXX",
    "sendEventPostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/abc123/raiseEvent/{eventName}?code=XXX",
    "statusQueryGetUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/abc123?code=XXX",
    "terminatePostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/abc123/terminate?reason={text}&code=XXX"
}

В предыдущем примере каждое из полей, оканчивающихся на Uri, соответствует встроенному API HTTP. Эти API можно использовать для управления целевым экземпляром оркестрации.

Примечание.

Формат URL-адресов веб-перехватчиков зависит от того, какая версия узла Функций Azure выполняется. Описанный выше пример предназначен для узла Функций Azure 2.0.

Описание всех встроенных API HTTP см. в справочнике по API HTTP.

Отслеживание асинхронных операций

Упомянутый ранее HTTP-ответ предназначен для помощи в реализации долго выполняющихся асинхронных API-интерфейсов HTTP с устойчивыми функциями. Такой шаблон иногда называется шаблоном опрашивающего объекта-получателя. Поток клиента или сервера работает следующим образом:

  1. Клиент отправляет запрос HTTP для запуска длительного процесса, например функции оркестратора.
  2. Целевой триггер HTTP возвращает ответ HTTP 202 с заголовком Location со значением "statusQueryGetUri".
  3. Клиент отправляет URL-адрес в заголовке Location. Он продолжает просматривать ответы HTTP 202 с заголовком Location.
  4. При завершении (или сбое) экземпляра конечная точка в заголовке Location возвращает ответ HTTP 200.

Этот протокол позволяет согласовать долго выполняющиеся процессы с помощью внешних клиентов или служб, которые могут отправлять запрос конечной точки HTTP и используют заголовок Location. Серверные и клиентские реализации этого шаблона встроены в API-интерфейсы HTTP службы "Устойчивые функции".

Примечание.

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

Примечание.

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

Дополнительные сведения об управлении оркестрациями и сущностями с помощью клиентских API см. в статье об управлении экземплярами.

Использование API-интерфейсов HTTP

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

Начиная с версии 2.0 службы "Устойчивые функции", оркестрации могут использовать API-интерфейсы HTTP с помощью привязки триггера оркестрации.

В следующем примере кода показана функция оркестратора, выполняющая исходящий HTTP-запрос:

[FunctionName("CheckSiteAvailable")]
public static async Task CheckSiteAvailable(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    Uri url = context.GetInput<Uri>();

    // Makes an HTTP GET request to the specified endpoint
    DurableHttpResponse response = 
        await context.CallHttpAsync(HttpMethod.Get, url);

    if (response.StatusCode >= 400)
    {
        // handling of error codes goes here
    }
}

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

  • Вызывать API HTTP непосредственно из функций оркестрации с некоторыми ограничениями, упомянутыми ниже.
  • Автоматически поддерживать шаблоны опроса состояния HTTP 202 на стороне клиента.
  • Использовать управляемые удостоверения Azure для выполнения санкционированных вызовов HTTP к другим конечным точкам Azure.

Возможность использования API-интерфейсов HTTP непосредственно из функций оркестратора предназначена для удобства работы с определенным набором распространенных сценариев. Все эти функции можно реализовать самостоятельно с помощью функций действий. Во многих случаях функции действий могут обеспечить большую гибкость.

Обработка HTTP 202

API "вызов HTTP" может автоматически реализовать клиентскую сторону шаблона опрашивающего объекта-получателя. Если вызываемый API возвращает ответ HTTP 202 с заголовком Location, функция оркестратора автоматически опрашивает ресурс расположения, пока не получит ответ, отличный от 202. Ответ будет возвращен в код функции оркестратора.

Примечание.

  1. Функции оркестратора также изначально поддерживают шаблон опрашивающего объекта-получателя на стороне сервера, как описано в разделе Отслеживание асинхронных операций. Такая поддержка означает, что согласование в одном приложении-функции может легко координировать функции оркестратора в других приложениях-функциях. Это похоже на концепцию вложенной оркестрации, но с поддержкой взаимодействия между приложениями. Эта поддержка особенно полезна при разработке приложений в стиле микрослужб.
  2. Из-за временного ограничения встроенный шаблон опроса HTTP в настоящее время недоступен в JavaScript/TypeScript и Python.

Управляемые удостоверения

Устойчивые функции изначально поддерживает вызовы API, которые принимают маркеры Microsoft Entra для авторизации. Эта поддержка использует управляемые удостоверения Azure для получения этих маркеров.

Следующий код является примером функции оркестратора. Функция выполняет проверку подлинности вызовов для перезапуска виртуальной машины с помощью REST API виртуальных машин Azure Resource Manager.

[FunctionName("RestartVm")]
public static async Task RunOrchestrator(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    string subscriptionId = "mySubId";
    string resourceGroup = "myRG";
    string vmName = "myVM";
    string apiVersion = "2019-03-01";
    
    // Automatically fetches an Azure AD token for resource = https://management.core.windows.net/.default
    // and attaches it to the outgoing Azure Resource Manager API call.
    var restartRequest = new DurableHttpRequest(
        HttpMethod.Post, 
        new Uri($"https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.Compute/virtualMachines/{vmName}/restart?api-version={apiVersion}"),
        tokenSource: new ManagedIdentityTokenSource("https://management.core.windows.net/.default"));
    DurableHttpResponse restartResponse = await context.CallHttpAsync(restartRequest);
    if (restartResponse.StatusCode != HttpStatusCode.OK)
    {
        throw new ArgumentException($"Failed to restart VM: {restartResponse.StatusCode}: {restartResponse.Content}");
    }
}

В предыдущем примере tokenSource параметр настроен для получения токенов Microsoft Entra для Azure Resource Manager. Маркеры идентифицируются с помощью URI ресурса https://management.core.windows.net/.default. В этом примере предполагается, что текущее приложение-функция выполняется локально или развернуто как приложение-функция с управляемым удостоверением. Предполагается, что локальным удостоверениям или управляемым удостоверениям предоставлено разрешение на управление виртуальными машинами в указанной группе ресурсов myRG.

Во время выполнения настроенный источник маркера автоматически возвращает маркер доступа OAuth 2.0. Затем источник добавляет маркер в качестве маркера носителя в заголовок авторизации исходящего запроса. Эта модель является улучшением по сравнению с добавлением заголовков авторизации вручную в HTTP-запросы по следующим причинам.

  • Обновление маркера обрабатывается автоматически. Вам не нужно беспокоиться о маркерах с истекшим сроком действия.
  • Маркеры никогда не хранятся в состоянии устойчивой оркестрации.
  • Вам не нужно писать код для управления получением маркера.

Более полный пример можно найти в предварительно скомпилированном примере C# RestartVMs.

Управляемые удостоверения не ограничиваются управлением ресурсами Azure. Управляемые удостоверения можно использовать для доступа к любому API, который принимает маркеры носителя Microsoft Entra, включая службы Azure из Майкрософт и веб-приложений от партнеров. Партнерское веб-приложение может даже быть другим приложением-функцией. Список служб Azure от Майкрософт, поддерживающих проверку подлинности с помощью идентификатора Microsoft Entra, см . в службах Azure, поддерживающих проверку подлинности Microsoft Entra.

Ограничения

Встроенная поддержка вызова API-интерфейсов HTTP — это вспомогательная функция. Она подходит не для всех сценариев.

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

  • Каждый HTTP-запрос требует дополнительной задержки по сравнению с собственным HTTP-клиентом.
  • В зависимости от настроенного поставщика хранилища большие сообщения запроса или ответа могут значительно снизить производительность оркестрации. Например, при использовании службы хранилища Azure полезные данные HTTP, которые слишком велики для размещения в сообщениях очереди Azure, сжимаются и сохраняются в хранилище BLOB-объектов Azure.
  • Потоковая передача, фрагментированность и двоичные данные не поддерживаются.
  • Возможность настройки поведения клиента HTTP ограничена.

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

Примечание.

Если вы являетесь разработчиком .NET, вас может быть интересно, почему эта функция использует типы DurableHttpRequest и DurableHttpResponse вместо встроенных типов .NET HttpRequestMessage и HttpResponseMessage.

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

Расширяемость (только .NET)

Настройка поведения внутреннего HTTP-клиента оркестрации возможна с помощью внедрения зависимостей .NET для функций Azure. Эта возможность может быть полезной для внесения небольших изменений в поведение. Она также может быть полезна для модульного тестирования HTTP-клиента путем внедрения макетов объектов.

В следующем примере демонстрируется использование внедрения зависимостей для отключения проверки сертификата TLS/SSL для функций оркестратора, вызывающих внешние конечные точки HTTP.

public class Startup : FunctionsStartup
{
    public override void Configure(IFunctionsHostBuilder builder)
    {
        // Register own factory
        builder.Services.AddSingleton<
            IDurableHttpMessageHandlerFactory,
            MyDurableHttpMessageHandlerFactory>();
    }
}

public class MyDurableHttpMessageHandlerFactory : IDurableHttpMessageHandlerFactory
{
    public HttpMessageHandler CreateHttpMessageHandler()
    {
        // Disable TLS/SSL certificate validation (not recommended in production!)
        return new HttpClientHandler
        {
            ServerCertificateCustomValidationCallback =
                HttpClientHandler.DangerousAcceptAnyServerCertificateValidator,
        };
    }
}

Следующие шаги