Что такое Устойчивые функции?What are Durable Functions?

Устойчивые функции — это расширение Функций Azure, которое позволяет писать функции с отслеживанием состояния в беcсерверной вычислительной среде.Durable Functions is an extension of Azure Functions that lets you write stateful functions in a serverless compute environment. Расширение позволяет определять рабочие процессы с отслеживанием состояния, создавая функции оркестратора, и сущности с отслеживанием состояния, создавая функции сущностей с помощью модели программирования Функций Azure.The extension lets you define stateful workflows by writing orchestrator functions and stateful entities by writing entity functions using the Azure Functions programming model. В фоновом режиме расширение автоматически управляет состоянием, создает контрольные точки и перезагружается, позволяя вам сосредоточиться на бизнес-логике.Behind the scenes, the extension manages state, checkpoints, and restarts for you, allowing you to focus on your business logic.

Поддерживаемые языкиSupported languages

Устойчивые функции в настоящее время поддерживают следующие языки.Durable Functions currently supports the following languages:

  • C# : обе предварительно скомпилированные библиотеки классов и сценарий C#.C#: both precompiled class libraries and C# script.
  • JavaScript: поддерживается только для версии 2.x среды выполнения Функций Azure.JavaScript: supported only for version 2.x of the Azure Functions runtime. Требуется расширение устойчивых функций версии 1.7.0 или более поздней версии.Requires version 1.7.0 of the Durable Functions extension, or a later version.
  • F# : предварительно скомпилированные библиотеки классов и сценарий F#.F#: precompiled class libraries and F# script. Сценарий F# (.fsx) поддерживается только в среде выполнения Функций Azure версии 1.x.F# script is only supported for version 1.x of the Azure Functions runtime.

Целью устойчивых функций является поддержка всех языков Функций Azure.Durable Functions has a goal of supporting all Azure Functions languages. См. здесь список проблем Устойчивых функций для получения последних сведений о состоянии работы для поддержки дополнительных языков.See the Durable Functions issues list for the latest status of work to support additional languages.

Подобно Функциям Azure, доступны шаблоны, которые помогут вам в разработке устойчивых функций с помощью Visual Studio 2019, Visual Studio Code и портала Azure.Like Azure Functions, there are templates to help you develop Durable Functions using Visual Studio 2019, Visual Studio Code, and the Azure portal.

Шаблоны приложенийApplication patterns

Основной вариант использования Устойчивых функций — это упрощение комплексных требований координации с отслеживанием состояния в безсерверных приложениях.The primary use case for Durable Functions is simplifying complex, stateful coordination requirements in serverless applications. В следующих разделах описываются типичные шаблоны приложений, в которых можно эффективно использовать Устойчивые функции.The following sections describe typical application patterns that can benefit from Durable Functions:

Шаблон 1. Цепочка функцийPattern #1: Function chaining

В шаблоне цепочки функций последовательность функций выполняется в определенном порядке.In the function chaining pattern, a sequence of functions executes in a specific order. В этом шаблоне выходные данные одной функции применяются к входным данным другой.In this pattern, the output of one function is applied to the input of another function.

Схема шаблона цепочки функций

Устойчивые функции можно использовать для реализации шаблона цепочки функций, как показано в следующем примере.You can use Durable Functions to implement the function chaining pattern concisely as shown in the following example.

В этом примере значения F1, F2, F3 и F4 являются именами других функций в том же приложении-функции.In this example, the values F1, F2, F3, and F4 are the names of other functions in the same function app. Поток управления можно реализовать с помощью обычных принудительных конструкций программирования.You can implement control flow by using normal imperative coding constructs. Код выполняется сверху вниз.Code executes from the top down. Код может включать в себя имеющуюся семантику языка потока управления, такую ​​как условные обозначения и циклы.The code can involve existing language control flow semantics, like conditionals and loops. Вы можете включить логику обработки ошибок в блоках try/catch/finally.You can include error handling logic in try/catch/finally blocks.

[FunctionName("Chaining")]
public static async Task<object> Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    try
    {
        var x = await context.CallActivityAsync<object>("F1", null);
        var y = await context.CallActivityAsync<object>("F2", x);
        var z = await context.CallActivityAsync<object>("F3", y);
        return  await context.CallActivityAsync<object>("F4", z);
    }
    catch (Exception)
    {
        // Error handling or compensation goes here.
    }
}

Вы можете использовать параметр context для вызова других функций по имени, передачи параметров и возврата выходных данных функции.You can use the context parameter to invoke other functions by name, pass parameters, and return function output. Каждый раз, когда код вызывает await, платформа Устойчивых функций создает контрольные точки выполнения текущего экземпляра функции.Each time the code calls await, the Durable Functions framework checkpoints the progress of the current function instance. Если процесс или виртуальная машина перезапускается во время выполнения, экземпляр функции возобновляется из предыдущего вызова await.If the process or virtual machine recycles midway through the execution, the function instance resumes from the preceding await call. Этот процесс описан в следующем разделе Шаблон 2: развертывание и объединение.For more information, see the next section, Pattern #2: Fan out/fan in.

Шаблон 2. Развертывание и объединениеPattern #2: Fan out/fan in

В шаблоне развертывания и объединения вы выполняете параллельно несколько функций, а затем ожидаете их завершения.In the fan out/fan in pattern, you execute multiple functions in parallel and then wait for all functions to finish. Часто некоторые агрегирования завершаются по результатам, возвращаемым функциями.Often, some aggregation work is done on the results that are returned from the functions.

Схема шаблона развертывания и объединения

При использовании обычных функций вы можете выполнить развертывание за счет отправки функцией нескольких сообщений в очередь.With normal functions, you can fan out by having the function send multiple messages to a queue. Войти обратно гораздо сложнее.Fanning back in is much more challenging. Чтобы выполнить объединение в обычной функции, напишите код для отслеживания момента, когда функции, активируемые очередью, завершаются, а затем их выходные значения сохраняются.To fan in, in a normal function, you write code to track when the queue-triggered functions end, and then store function outputs.

Расширение "Устойчивые функции" обрабатывает этот шаблон с помощью относительно простого кода:The Durable Functions extension handles this pattern with relatively simple code:

[FunctionName("FanOutFanIn")]
public static async Task Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var parallelTasks = new List<Task<int>>();

    // Get a list of N work items to process in parallel.
    object[] workBatch = await context.CallActivityAsync<object[]>("F1", null);
    for (int i = 0; i < workBatch.Length; i++)
    {
        Task<int> task = context.CallActivityAsync<int>("F2", workBatch[i]);
        parallelTasks.Add(task);
    }

    await Task.WhenAll(parallelTasks);

    // Aggregate all N outputs and send the result to F3.
    int sum = parallelTasks.Sum(t => t.Result);
    await context.CallActivityAsync("F3", sum);
}

Процесс развертывания распределяется по нескольким экземплярам функции F2.The fan-out work is distributed to multiple instances of the F2 function. И отслеживается с использованием динамического списка задач.The work is tracked by using a dynamic list of tasks. Task.WhenAll вызывается для ожидания завершения всех вызванных функций.Task.WhenAll is called to wait for all the called functions to finish. Затем выходные данные функции F2 агрегируются из списка динамических задач и передаются функции F3.Then, the F2 function outputs are aggregated from the dynamic task list and passed to the F3 function.

Автоматическое создание контрольных точек, которое происходит при вызове await к Task.WhenAll, гарантирует, что возможный сбой или перезагрузка во время выполнения не потребуют перезапуска уже завершенной задачи.The automatic checkpointing that happens at the await call on Task.WhenAll ensures that a potential midway crash or reboot doesn't require restarting an already completed task.

Примечание

В редких случаях может произойти сбой в окне после завершения функции действия, но до того, как ее выполнение будет сохранено в журнале оркестрации.In rare circumstances, it's possible that a crash could happen in the window after an activity function completes but before its completion is saved into the orchestration history. В этом случае функция действия будет повторно выполнена с начала после восстановления процесса.If this happens, the activity function would re-run from the beginning after the process recovers.

Шаблон 3. Асинхронные API-интерфейсы HTTPPattern #3: Async HTTP APIs

Шаблон асинхронного API HTTP решает проблему координации состояния длительных операций с внешними клиентами.The async HTTP API pattern addresses the problem of coordinating the state of long-running operations with external clients. Распространенный способ реализации этого шаблона — наличие триггера конечной точки HTTP для выполнения длительного действия.A common way to implement this pattern is by having an HTTP endpoint trigger the long-running action. Затем перенаправьте клиент на конечную точку состояния, которую клиент опрашивает для получения сведений о завершении операции.Then, redirect the client to a status endpoint that the client polls to learn when the operation is finished.

Схема шаблона API HTTP

Устойчивые функции предоставляют встроенную поддержку для этого шаблона, упрощая или даже удаляя код, который вам нужно написать для взаимодействия с длительными выполнениями функций.Durable Functions provides built-in support for this pattern, simplifying or even removing the code you need to write to interact with long-running function executions. Например, в примерах из краткого руководства по Устойчивым функциям (C# и JavaScript) показана простая команда REST, которую вы можете использовать для запуска новых экземпляров функции оркестратора.For example, the Durable Functions quickstart samples (C# and JavaScript) show a simple REST command that you can use to start new orchestrator function instances. После запуска экземпляра расширение предоставляет API HTTP веб-перехватчика, которые запрашивают состояние функции оркестратора.After an instance starts, the extension exposes webhook HTTP APIs that query the orchestrator function status.

В следующем примере показаны команды REST, которые запускают оркестратор и запрашивают его состояние.The following example shows REST commands that start an orchestrator and query its status. Для ясности в примере опущены некоторые данные протокола.For clarity, some protocol details are omitted from the example.

> curl -X POST https://myfunc.azurewebsites.net/orchestrators/DoWork -H "Content-Length: 0" -i
HTTP/1.1 202 Accepted
Content-Type: application/json
Location: https://myfunc.azurewebsites.net/runtime/webhooks/durabletask/b79baf67f717453ca9e86c5da21e03ec

{"id":"b79baf67f717453ca9e86c5da21e03ec", ...}

> curl https://myfunc.azurewebsites.net/runtime/webhooks/durabletask/b79baf67f717453ca9e86c5da21e03ec -i
HTTP/1.1 202 Accepted
Content-Type: application/json
Location: https://myfunc.azurewebsites.net/runtime/webhooks/durabletask/b79baf67f717453ca9e86c5da21e03ec

{"runtimeStatus":"Running","lastUpdatedTime":"2019-03-16T21:20:47Z", ...}

> curl https://myfunc.azurewebsites.net/runtime/webhooks/durabletask/b79baf67f717453ca9e86c5da21e03ec -i
HTTP/1.1 200 OK
Content-Length: 175
Content-Type: application/json

{"runtimeStatus":"Completed","lastUpdatedTime":"2019-03-16T21:20:57Z", ...}

Так как управление состоянием осуществляется средой выполнения Устойчивых функций, вам не нужно реализовывать собственный механизм отслеживания состояния.Because the Durable Functions runtime manages state for you, you don't need to implement your own status-tracking mechanism.

Расширение "Устойчивые функции" предоставляет встроенные API HTTP, которые управляют длительными оркестрациями.The Durable Functions extension exposes built-in HTTP APIs that manage long-running orchestrations. Вы также можете реализовать этот шаблон самостоятельно, используя собственные триггеры функций (например, HTTP, очередь или Центры событий Azure) и привязку клиента оркестрации.You can alternatively implement this pattern yourself by using your own function triggers (such as HTTP, a queue, or Azure Event Hubs) and the orchestration client binding. Например, для активации действия прекращения можно использовать сообщение очереди.For example, you might use a queue message to trigger termination. Или можно использовать триггер HTTP, защищенный политикой проверки подлинности Azure Active Directory, вместо встроенных API-интерфейсов HTTP с созданным ключом для проверки подлинности.Or, you might use an HTTP trigger that's protected by an Azure Active Directory authentication policy instead of the built-in HTTP APIs that use a generated key for authentication.

Дополнительные сведения см. в статье о функциях HTTP, в которой объясняется, как можно предоставлять асинхронные длительные процессы по протоколу HTTP с помощью расширения "Устойчивые функции".For more information, see the HTTP features article, which explains how you can expose asynchronous, long-running processes over HTTP using the Durable Functions extension.

Шаблон 4. МониторPattern #4: Monitor

Шаблон мониторинга представляет собой гибкий, повторяющийся процесс в рабочем процессе.The monitor pattern refers to a flexible, recurring process in a workflow. Например, повторение опроса, пока не будут выполнены определенные условия.An example is polling until specific conditions are met. Вы можете использовать регулярный триггер таймера для активации основного сценария, например задание периодической очистки. Но интервал является статическим, что усложняет управление временем существования экземпляра.You can use a regular timer trigger to address a basic scenario, such as a periodic cleanup job, but its interval is static and managing instance lifetimes becomes complex. Вы можете использовать Устойчивые функции, чтобы создать гибкие интервалы повторения, управлять временем существования задачи и создавать несколько процессов мониторинга в рамках одной оркестрации.You can use Durable Functions to create flexible recurrence intervals, manage task lifetimes, and create multiple monitor processes from a single orchestration.

Примером шаблона мониторинга является измененный сценарий асинхронных API-интерфейсов HTTP, приведенный ранее.An example of the monitor pattern is to reverse the earlier async HTTP API scenario. Вместо предоставления конечной точки внешнему клиенту для мониторинга длительной операции, мониторинг использует внешнюю конечную точку, а затем ожидает изменение состояния.Instead of exposing an endpoint for an external client to monitor a long-running operation, the long-running monitor consumes an external endpoint, and then waits for a state change.

Схема шаблона мониторинга

Благодаря нескольким строкам кода можно использовать Устойчивые функции, чтобы создать несколько мониторингов, которые наблюдают за произвольными конечными точками.In a few lines of code, you can use Durable Functions to create multiple monitors that observe arbitrary endpoints. Работа мониторингов может приостановиться, если выполнено условие, или другая функция может использовать клиент оркестрации для завершения мониторинга.The monitors can end execution when a condition is met, or another function can use the durable orchestration client to terminate the monitors. Можно изменить интервал мониторинга wait в зависимости от определенного условия (например, экспоненциальной задержки).You can change a monitor's wait interval based on a specific condition (for example, exponential backoff.)

В следующем коде реализуется простой мониторинг:The following code implements a basic monitor:

[FunctionName("MonitorJobStatus")]
public static async Task Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    int jobId = context.GetInput<int>();
    int pollingInterval = GetPollingInterval();
    DateTime expiryTime = GetExpiryTime();

    while (context.CurrentUtcDateTime < expiryTime)
    {
        var jobStatus = await context.CallActivityAsync<string>("GetJobStatus", jobId);
        if (jobStatus == "Completed")
        {
            // Perform an action when a condition is met.
            await context.CallActivityAsync("SendAlert", machineId);
            break;
        }

        // Orchestration sleeps until this time.
        var nextCheck = context.CurrentUtcDateTime.AddSeconds(pollingInterval);
        await context.CreateTimer(nextCheck, CancellationToken.None);
    }

    // Perform more work here, or let the orchestration end.
}

При получении запроса создается экземпляр оркестрации для указанного идентификатора события.When a request is received, a new orchestration instance is created for that job ID. Экземпляр выполняет опрос состояния, пока не выполнится условие или не произойдет выход из цикла.The instance polls a status until a condition is met and the loop is exited. Для управления интервалом опроса используется устойчивый таймер.A durable timer controls the polling interval. После этого можно перейти к другим задачам или завершить оркестрацию.Then, more work can be performed, or the orchestration can end. Когда nextCheck превышает expiryTime, монитор останавливается.When nextCheck exceeds expiryTime, the monitor ends.

Шаблон 5. Участие пользователяPattern #5: Human interaction

Многие автоматизированные процессы требуют некоторого участия пользователя.Many automated processes involve some kind of human interaction. Трудность вовлечения людей в автоматизированный процесс заключается в том, что пользователи не так доступны и не так быстро реагируют, как облачные службы.Involving humans in an automated process is tricky because people aren't as highly available and as responsive as cloud services. Автоматизированный процесс должен учитывать это. Для этого используется время ожидания и логика компенсации.An automated process might allow for this interaction by using timeouts and compensation logic.

Процесс утверждения является примером бизнес-процесса, который предполагает взаимодействие с пользователями.An approval process is an example of a business process that involves human interaction. Утверждение от менеджера может потребоваться для отчета о расходах, превышающих определенную денежную сумму.Approval from a manager might be required for an expense report that exceeds a certain dollar amount. Если менеджер не подтверждает отчет о расходах в течение 72 часов (возможно, он отправился в отпуск), начинается процесс эскалации, чтобы получить одобрение от кого-то другого (возможно, вышестоящего менеджера).If the manager doesn't approve the expense report within 72 hours (maybe the manager went on vacation), an escalation process kicks in to get the approval from someone else (perhaps the manager's manager).

Схема шаблона участия пользователя

Этот шаблон в примере можно реализовать с помощью функции оркестратора.You can implement the pattern in this example by using an orchestrator function. Оркестратор использует устойчивый таймер, чтобы запросить одобрение.The orchestrator uses a durable timer to request approval. Оркестратор начинает эскалацию, если истекло время ожидания.The orchestrator escalates if timeout occurs. Он ожидает внешнее событие в виде уведомления, созданного в результате участия пользователя.The orchestrator waits for an external event, such as a notification that's generated by a human interaction.

В этих примерах создается процесс утверждения для демонстрации шаблона участия пользователя:These examples create an approval process to demonstrate the human interaction pattern:

[FunctionName("ApprovalWorkflow")]
public static async Task Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    await context.CallActivityAsync("RequestApproval", null);
    using (var timeoutCts = new CancellationTokenSource())
    {
        DateTime dueTime = context.CurrentUtcDateTime.AddHours(72);
        Task durableTimeout = context.CreateTimer(dueTime, timeoutCts.Token);

        Task<bool> approvalEvent = context.WaitForExternalEvent<bool>("ApprovalEvent");
        if (approvalEvent == await Task.WhenAny(approvalEvent, durableTimeout))
        {
            timeoutCts.Cancel();
            await context.CallActivityAsync("ProcessApproval", approvalEvent.Result);
        }
        else
        {
            await context.CallActivityAsync("Escalate", null);
        }
    }
}

Для создания устойчивого таймера вызовите context.CreateTimer.To create the durable timer, call context.CreateTimer. Уведомление получает context.WaitForExternalEvent.The notification is received by context.WaitForExternalEvent. Затем Task.WhenAny вызывается для того, чтобы решить, следует ли ускорить процесс (сначала истечет время ожидания) или утвердить процесс (утверждение получено до истечения времени ожидания).Then, Task.WhenAny is called to decide whether to escalate (timeout happens first) or process the approval (the approval is received before timeout).

Внешний клиент может доставить уведомление о событии в функцию оркестратора, находящуюся в состоянии ожидания, через встроенные интерфейсы API HTTP:An external client can deliver the event notification to a waiting orchestrator function by using the built-in HTTP APIs:

curl -d "true" http://localhost:7071/runtime/webhooks/durabletask/instances/{instanceId}/raiseEvent/ApprovalEvent -H "Content-Type: application/json"

Событие также можно вызвать с помощью клиента оркестрации устойчивых функций из другой функции в том же приложении-функции:An event can also be raised using the durable orchestration client from another function in the same function app:

[FunctionName("RaiseEventToOrchestration")]
public static async Task Run(
    [HttpTrigger] string instanceId,
    [DurableClient] IDurableOrchestrationClient client)
{
    bool isApproved = true;
    await client.RaiseEventAsync(instanceId, "ApprovalEvent", isApproved);
}

Шаблон 6. Агрегатор (сущности с отслеживанием состояния)Pattern #6: Aggregator (stateful entities)

Шестой шаблон заключается в статистической обработке данных событий за определенный период времени в одну доступную для адресации сущность.The sixth pattern is about aggregating event data over a period of time into a single, addressable entity. В этом шаблоне данные, для которых выполняется агрегирование, могут поступать из нескольких источников, могут быть доставлены пакетами или разбросаны по длительным временным периодам.In this pattern, the data being aggregated may come from multiple sources, may be delivered in batches, or may be scattered over long-periods of time. Агрегатору может потребоваться выполнить действия над данными событий по мере их поступления, а внешним клиентам может потребоваться запросить агрегированные данные.The aggregator might need to take action on event data as it arrives, and external clients may need to query the aggregated data.

Схема агрегатора

Сложности при реализации этого шаблона с обычными функциями без отслеживания состояния заключаются в том, что управление параллелизмом крайне усложняется.The tricky thing about trying to implement this pattern with normal, stateless functions is that concurrency control becomes a huge challenge. Нужно не только беспокоиться о том, что несколько потоков одновременно изменяют одни и те же данные, также важно и то, чтобы агрегатор одновременно выполнялся только на одной виртуальной машине.Not only do you need to worry about multiple threads modifying the same data at the same time, you also need to worry about ensuring that the aggregator only runs on a single VM at a time.

Устойчивые сущности можно использовать, чтобы легко реализовать этот шаблон как отдельную функцию.You can use Durable entities to easily implement this pattern as a single function.

[FunctionName("Counter")]
public static void Counter([EntityTrigger] IDurableEntityContext ctx)
{
    int currentValue = ctx.GetState<int>();
    switch (ctx.OperationName.ToLowerInvariant())
    {
        case "add":
            int amount = ctx.GetInput<int>();
            ctx.SetState(currentValue + amount);
            break;
        case "reset":
            ctx.SetState(0);
            break;
        case "get":
            ctx.Return(currentValue);
            break;
    }
}

Устойчивые сущности можно также моделировать как классы в .NET.Durable entities can also be modeled as classes in .NET. Эта модель может быть полезной, если список операций является фиксированным и становится большим.This model can be useful if the list of operations is fixed and becomes large. Следующий пример представляет собой эквивалентную реализацию сущности Counter с помощью классов и методов .NET.The following example is an equivalent implementation of the Counter entity using .NET classes and methods.

public class Counter
{
    [JsonProperty("value")]
    public int CurrentValue { get; set; }

    public void Add(int amount) => this.CurrentValue += amount;

    public void Reset() => this.CurrentValue = 0;

    public int Get() => this.CurrentValue;

    [FunctionName(nameof(Counter))]
    public static Task Run([EntityTrigger] IDurableEntityContext ctx)
        => ctx.DispatchAsync<Counter>();
}

Клиенты могут поставить в очередь операции (называемые также "сигнализацией") для функции сущности, использующей привязку клиента сущности.Clients can enqueue operations for (also known as "signaling") an entity function using the entity client binding.

[FunctionName("EventHubTriggerCSharp")]
public static async Task Run(
    [EventHubTrigger("device-sensor-events")] EventData eventData,
    [DurableClient] IDurableOrchestrationClient entityClient)
{
    var metricType = (string)eventData.Properties["metric"];
    var delta = BitConverter.ToInt32(eventData.Body, eventData.Body.Offset);

    // The "Counter/{metricType}" entity is created on-demand.
    var entityId = new EntityId("Counter", metricType);
    await entityClient.SignalEntityAsync(entityId, "add", delta);
}

Примечание

Динамически создаваемые прокси-серверы также доступны в .NET для сигнализации сущностям типобезопасным способом.Dynamically generated proxies are also available in .NET for signaling entities in a type-safe way. Кроме сигнализации, клиенты также могут запрашивать состояние функции сущности с помощью типобезопасных методов в привязке клиента оркестрации.And in addition to signaling, clients can also query for the state of an entity function using type-safe methods on the orchestration client binding.

Функции сущности доступны в Устойчивых функциях 2.0 и более поздних версиях.Entity functions are available in Durable Functions 2.0 and above.

ТехнологияThe technology

Расширение "Устойчивые функции" создано на платформе устойчивых задач, библиотеки с открытым кодом на GitHub для создания рабочих процессов в коде.Behind the scenes, the Durable Functions extension is built on top of the Durable Task Framework, an open-source library on GitHub that's used to build workflows in code. Подобно тому, как Функции Azure являются бессерверным развитием веб-заданий Azure, Устойчивые функции — это бессерверное развитие платформы устойчивых задач.Like Azure Functions is the serverless evolution of Azure WebJobs, Durable Functions is the serverless evolution of the Durable Task Framework. Платформа устойчивых задач широко используется как корпорацией Майкрософт, так и другими организациями для автоматизации критически важных процессов.Microsoft and other organizations use the Durable Task Framework extensively to automate mission-critical processes. Это естественный выбор для бессерверной среды функций Azure.It's a natural fit for the serverless Azure Functions environment.

Ограничения кодаCode constraints

Чтобы обеспечить надежность и гарантировать длительное выполнение, в функциях оркестратора предусмотрен набор правил кода, которым нужно следовать.In order to provide reliable and long-running execution guarantees, orchestrator functions have a set of coding rules that must be followed. Дополнительные сведения см. в статье Orchestrator function code constraints (Ограничения кода функции оркестратора).For more information, see the Orchestrator function code constraints article.

Выставление счетовBilling

Счета за устойчивые функции выставляются так же, как и за Функции Azure.Durable Functions are billed the same as Azure Functions. Дополнительные сведения см. на странице цен на Функции Azure.For more information, see Azure Functions pricing. При выполнении функций оркестратора в рамках плана потребления Функций Azure необходимо учитывать некоторые особенности при выставлении счетов.When executing orchestrator functions in the Azure Functions Consumption plan, there are some billing behaviors to be aware of. Дополнительные сведения об этом см. в статье Durable Functions Billing (Выставление счетов за Устойчивые функции).For more information on these behaviors, see the Durable Functions billing article.

Приступайте к работеJump right in

Вы можете начать работу с Устойчивыми функциями менее чем за 10 минут, просмотрев одно из следующих кратких руководств по конкретным языкам.You can get started with Durable Functions in under 10 minutes by completing one of these language-specific quickstart tutorials:

В обоих кратких руководствах вы локально создаете и тестируете устойчивую функцию "Hello world".In both quickstarts, you locally create and test a "hello world" durable function. Затем вы опубликуете код функции в Azure.You then publish the function code to Azure. Функция, которую вы создаете, организовывает и объединяет в цепочку вызовы других функций.The function you create orchestrates and chains together calls to other functions.

Дополнительные сведенияLearn more

В следующем видео показаны преимущества Устойчивых функций.The following video highlights the benefits of Durable Functions:

Более подробное обсуждение Устойчивых функций и базовой технологии см. в следующем видео (оно ориентировано на .NET, но понятия также применимы и к другим поддерживаемым языкам):For a more in-depth discussion of Durable Functions and the underlying technology, see the following video (it's focused on .NET, but the concepts also apply to other supported languages):

Так как Устойчивые функции — это дополнительное расширение решения Функции Azure, оно подходит не для всех приложений.Because Durable Functions is an advanced extension for Azure Functions, it isn't appropriate for all applications. Сравнение с другими технологиями оркестрации Azure см. в разделе Сравнение служб "Функции Azure" и Azure Logic Apps.For a comparison with other Azure orchestration technologies, see Compare Azure Functions and Azure Logic Apps.

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

Durable Functions types and features (Azure Functions) (Типы и возможности Устойчивых функций (Функции Azure))Durable Functions function types and features