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


Устойчивые оркестрации

Устойчивые функции — это расширение функций Azure. Функцию оркестратора можно использовать для оркестрации выполнения других устойчивых функций в приложении-функции. Функции Оркестратора имеют следующие характеристики:

  • Функции Оркестратора определяют рабочие процессы функций с помощью процедурного кода. Декларативные схемы или конструкторы не требуются.
  • Функции Оркестратора могут вызывать другие устойчивые функции синхронно и асинхронно. Выходные данные из вызываемой функции можно надежно сохранить в локальных переменных.
  • Функции оркестратора являются устойчивыми и надежными. Автоматическая фиксация прогресса выполнения происходит в момент, когда функция "awaits" или "приостанавливает". Локальное состояние никогда не теряется при перезапуске процесса или перезагрузке виртуальной машины.
  • Функции оркестратора могут быть длительными. Общий срок службы экземпляра оркестрации может составлять секунды, дни, месяцы или быть бесконечным.

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

Идентификация оркестрации

Каждый экземпляр оркестрации имеет идентификатор экземпляра (также известный как идентификатор экземпляра). По умолчанию каждый идентификатор экземпляра является автоматически созданным GUID. Однако идентификаторы экземпляров также могут быть любым пользовательским строковым значением. Каждый идентификатор экземпляра оркестрации должен быть уникальным в узле задач.

Ниже приведены некоторые правила для идентификаторов экземпляров:

  • Идентификаторы должны быть от 1 до 100 символов.
  • Идентификаторы экземпляров не должны начинаться с @.
  • Идентификаторы экземпляров не должны содержать /, \#или ? символы.
  • Идентификаторы экземпляров не должны содержать управляющие символы.

Замечание

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

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

Идентификатор экземпляра оркестрации является обязательным параметром для большинства операций управления экземплярами. Они также важны для диагностики, например, как поиск среди данных отслеживания оркестрации в Application Insights для таких задач, как устранение неполадок или проведение анализа. По этой причине рекомендуется сохранить идентификаторы созданных экземпляров в некотором внешнем расположении (например, в базе данных или в журналах приложений), где к ним можно будет легко обратиться позже.

Reliability

Функции Оркестратора надежно поддерживают состояние выполнения с помощью шаблона конструктора событий . Вместо прямого хранения текущего состояния оркестрации фреймворк Durable Task использует хранилище с добавлением для записи полной последовательности действий, выполняемых оркестрацией функции. Хранилище только для добавления имеет множество преимуществ по сравнению со сбросом полного состояния во время выполнения. Преимущества включают повышение производительности, масштабируемости и реагирования. Кроме того, вы получаете постепенное достижение согласованности для транзакционных данных, а также полные следы аудита и истории. Журналы аудита обеспечивают надежные компенсирующие действия.

Устойчивые функции используют обработку событий прозрачно. За кулисами оператор await (C#) или yield (JavaScript/Python) в функции оркестратора передаёт управление потоком оркестратора обратно в диспетчер фреймворка устойчивых задач. В случае Java не существует специального ключевого слова языка. Вместо этого при вызове .await() управление задачей возвращается диспетчеру с помощью пользовательского Throwable. Затем диспетчер фиксирует любые новые действия, запланированные функцией оркестратора (например, вызов одной или нескольких дочерних функций или планирование устойчивого таймера) в хранилище. Действие прозрачной фиксации обновляет историю выполнения экземпляра оркестрации через добавление всех новых событий в хранилище, как ведение журнала только с операцией добавления. Аналогичным образом действие фиксации создает сообщения в хранилище для расписания выполнения фактической работы. На этом этапе функцию оркестратора можно выгрузить из памяти. По умолчанию Устойчивые функции используют службу хранилища Azure в качестве хранилища состояний среды выполнения, но поддерживаются и другие поставщики хранилища.

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

Замечание

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

Замечание

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

История оркестрации

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

Замечание

Общедоступна версия 4 модели программирования Node.js для функций Azure. Новая модель версии 4 предназначена для более гибкого и интуитивно понятного интерфейса для разработчиков JavaScript и TypeScript. Дополнительные сведения о различиях между версиями 3 и 4 см. в руководстве по миграции.

В следующих фрагментах кода JavaScript (PM4) обозначает модель программирования версии 4, новый интерфейс.

[FunctionName("HelloCities")]
public static async Task<List<string>> Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var outputs = new List<string>();

    outputs.Add(await context.CallActivityAsync<string>("SayHello", "Tokyo"));
    outputs.Add(await context.CallActivityAsync<string>("SayHello", "Seattle"));
    outputs.Add(await context.CallActivityAsync<string>("SayHello", "London"));

    // returns ["Hello Tokyo!", "Hello Seattle!", "Hello London!"]
    return outputs;
}

При планировании функции активности платформа устойчивых задач сохраняет состояние выполнения функции в устойчивое серверное хранилище, например, хранилище таблиц Azure по умолчанию. Это состояние известно как история оркестрации.

Таблица журнала

Как правило, платформа устойчивых задач выполняет следующие действия на каждой контрольной точке:

  1. Сохраняет журнал выполнения в устойчивом хранилище.
  2. Помещает сообщения в очередь для функций, которые оркестратор хочет вызвать.
  3. Ставит в очередь сообщения для самого оркестратора — например, долговечные таймерные сообщения.

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

Замечание

Служба хранилища Azure не предоставляет никаких гарантий транзакций между сохранением данных в хранилище таблиц и очередей. Для обработки сбоев поставщик Azure Storage для Durable Functions использует шаблоны согласованности по итогу. Эти шаблоны гарантируют, что данные не будут потеряны при сбое или потере подключения в середине контрольной точки. Альтернативные поставщики хранилища, такие как поставщик хранилища устойчивых функций MSSQL, могут обеспечить более надежные гарантии согласованности.

По завершении журнал функции, показанной ранее, выглядит примерно так, как в службе хранилища таблиц Azure (сокращено для иллюстрации):

PartitionKey (InstanceId) Тип события Отметка времени Ввод Имя Result Состояние
eaee885b Запуск выполнен 2021-05-05T18:45:28.852Z ноль HelloCities
eaee885b OrchestratorStarted 2021-05-05T18:45:32.362Z
eaee885b ЗадачаЗапланирована 2021-05-05T18:45:32.670Z Сайхелло
eaee885b OrchestratorCompleted 2021-05-05T18:45:32.670Z
eaee885b TaskCompleted 2021-05-05T18:45:34.201Z ""Hello Tokyo!""
eaee885b OrchestratorStarted 2021-05-05T18:45:34.232Z
eaee885b ЗадачаЗапланирована 2021-05-05T18:45:34.435Z Сайхелло
eaee885b OrchestratorCompleted 2021-05-05T18:45:34.435Z
eaee885b TaskCompleted 2021-05-05T18:45:34.763Z """Hello Сиэтл!""
eaee885b OrchestratorStarted 2021-05-05T18:45:34.857Z
eaee885b ЗадачаЗапланирована 2021-05-05T18:45:34.857Z Сайхелло
eaee885b ДиспетчерЗавершено 2021-05-05T18:45:34.857Z
eaee885b TaskCompleted 2021-05-05T18:45:34.919Z """Hello London!""
eaee885b Оркестратор запущен 2021-05-05T18:45:35.032Z
eaee885b Оркестратор завершён 2021-05-05T18:45:35.044Z
eaee885b ВыполнениеЗавершено 2021-05-05T18:45:35.044Z ["Привет, Токио!", "Привет, Сиэтл!", "Привет, Лондон!"] Завершено

Несколько заметок о значениях столбцов:

  • PartitionKey: содержит идентификатор экземпляра оркестрации.
  • EventType: представляет тип события. Подробные описания всех типов событий истории можно найти здесь.
  • Метка времени: время UTC события журнала.
  • Имя: имя вызываемой функции.
  • Входные данные: входные данные в формате JSON функции.
  • Результат: выходные данные функции; т. е. его возвращаемое значение.

Предупреждение

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

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

Функции и шаблоны

В следующих разделах описываются функции и шаблоны функций оркестратора.

Подоркестрации

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

Дополнительные сведения и примеры см. в статье о подоркестрациях.

Устойчивые таймеры

Оркестрации могут запланировать устойчивые таймеры для реализации задержек или настройки обработки времени ожидания для асинхронных действий. Используйте устойчивые таймеры в функциях оркестратора вместо встроенных в язык программирования функций sleep.

Дополнительные сведения и примеры см. в статье о устойчивых таймерах .

Внешние события

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

Дополнительные сведения и примеры см. в статье о внешних событиях .

Обработка ошибок

Функции оркестратора могут использовать функции обработки ошибок языка программирования. Существующие шаблоны, например try/catch , поддерживаются в коде оркестрации.

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

Замечание

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

Дополнительные сведения и примеры см. в статье об обработке ошибок .

Критические разделы (устойчивые функции 2.x, на данный момент только для .NET)

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

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

[FunctionName("Synchronize")]
public static async Task Synchronize(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var lockId = new EntityId("LockEntity", "MyLockIdentifier");
    using (await context.LockAsync(lockId))
    {
        // critical section - only one orchestration can enter at a time
    }
}

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

Функция критической секции также полезна для координации изменений долговечных объектов. Дополнительные сведения о критических разделах см. в разделе "Устойчивые сущности: координация сущностей".

Замечание

Критические разделы доступны в устойчивых функциях 2.0. В настоящее время только оркестрации .NET в proc реализуют эту функцию. Сущности и критически важные разделы пока недоступны в устойчивых функциях для точечной изолированной рабочей роли.

Вызов конечных точек HTTP (Durable Functions 2.x)

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

Чтобы упростить этот распространенный шаблон, функции оркестратора могут использовать CallHttpAsync метод для вызова API-интерфейсов 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 ((int)response.StatusCode == 400)
    {
        // handling of error codes goes here
    }
}

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

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

Замечание

Вызов конечных точек HTTP непосредственно из функций оркестратора доступен в Durable Functions версии 2.0 и выше.

Передача нескольких параметров

Невозможно передать несколько параметров в функцию действия напрямую. Рекомендация заключается в передаче массива объектов или составных объектов.

В .NET можно также использовать объекты ValueTuple . В следующем примере используются новые функции ValueTuple , добавленные с помощью C# 7:

[FunctionName("GetCourseRecommendations")]
public static async Task<object> RunOrchestrator(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    string major = "ComputerScience";
    int universityYear = context.GetInput<int>();

    object courseRecommendations = await context.CallActivityAsync<object>(
        "CourseRecommendations",
        (major, universityYear));
    return courseRecommendations;
}

[FunctionName("CourseRecommendations")]
public static async Task<object> Mapper([ActivityTrigger] IDurableActivityContext inputs)
{
    // parse input for student's major and year in university
    (string Major, int UniversityYear) studentInfo = inputs.GetInput<(string, int)>();

    // retrieve and return course recommendations by major and university year
    return new
    {
        major = studentInfo.Major,
        universityYear = studentInfo.UniversityYear,
        recommendedCourses = new []
        {
            "Introduction to .NET Programming",
            "Introduction to Linux",
            "Becoming an Entrepreneur"
        }
    };
}

Дальнейшие шаги