Обработка ошибок в устойчивых функциях (Функции Azure)

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

Примечание

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

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

Ошибки в функциях действий

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

Например, рассмотрим следующую функцию оркестратора, которая перемещает средства с одного счета на другой:

[FunctionName("TransferFunds")]
public static async Task Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var transferDetails = context.GetInput<TransferOperation>();

    await context.CallActivityAsync("DebitAccount",
        new
        {
            Account = transferDetails.SourceAccount,
            Amount = transferDetails.Amount
        });

    try
    {
        await context.CallActivityAsync("CreditAccount",
            new
            {
                Account = transferDetails.DestinationAccount,
                Amount = transferDetails.Amount
            });
    }
    catch (Exception)
    {
        // Refund the source account.
        // Another try/catch could be used here based on the needs of the application.
        await context.CallActivityAsync("CreditAccount",
            new
            {
                Account = transferDetails.SourceAccount,
                Amount = transferDetails.Amount
            });
    }
}

Примечание

Предыдущие примеры C# предназначены для расширения "Устойчивые функции" версии 2.x. Для расширения "Устойчивые функции" версии 1.x необходимо использовать DurableOrchestrationContext вместо IDurableOrchestrationContext. Дополнительные сведения о различиях между версиями см. в статье Версии устойчивых функций.

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

Автоматическое повторение попыток при сбое

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

[FunctionName("TimerOrchestratorWithRetry")]
public static async Task Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var retryOptions = new RetryOptions(
        firstRetryInterval: TimeSpan.FromSeconds(5),
        maxNumberOfAttempts: 3);

    await context.CallActivityWithRetryAsync("FlakyFunction", retryOptions, null);

    // ...
}

Примечание

Предыдущие примеры C# предназначены для расширения "Устойчивые функции" версии 2.x. Для расширения "Устойчивые функции" версии 1.x необходимо использовать DurableOrchestrationContext вместо IDurableOrchestrationContext. Дополнительные сведения о различиях между версиями см. в статье Версии устойчивых функций.

В вызове функции действия в предыдущем примере предусмотрен параметр для настройки политики автоматизации повторов. Существует несколько параметров настройки политики автоматического повтора.

  • Max number of attempts (Максимальное число попыток): максимальное число попыток. Если задано значение 1, повторная попытка не выполняется.
  • First retry interval (Интервал до первого повтора): время ожидания перед первой повторной попыткой.
  • Backoff coefficient (Коэффициент отсрочки): коэффициент, позволяющий определить степень увеличения отсрочки. По умолчанию равен 1.
  • Max retry interval (Максимальный интервал повтора): максимальное время ожидания между повторными попытками.
  • Retry timeout (Время ожидания повтора): максимальное время, отведенное на выполнение повторных попыток. Поведение по умолчанию — бесконечное повторение.

Пользовательские обработчики повторных попыток

При использовании .NET или Java вы также можете реализовать обработчики повторных попыток в коде. Это полезно, если декларативных политик повторных попыток недостаточно. Для языков, которые не поддерживают пользовательские обработчики повторных попыток, вы по-прежнему можете реализовать политики повторных попыток с помощью циклов, обработки исключений и таймеров для добавления задержек между повторными попытками.

RetryOptions retryOptions = new RetryOptions(
    firstRetryInterval: TimeSpan.FromSeconds(5),
    maxNumberOfAttempts: int.MaxValue)
    {
        Handle = exception =>
        {
            // True to handle and try again, false to not handle and throw.
            if (exception is TaskFailedException failure)
            {
                // Exceptions from TaskActivities are always this type. Inspect the
                // inner Exception to get more details.
            }

            return false;
        };
    }

await ctx.CallActivityWithRetryAsync("FlakeyActivity", retryOptions, null);

Время ожидания функций

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

[FunctionName("TimerOrchestrator")]
public static async Task<bool> Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
    TimeSpan timeout = TimeSpan.FromSeconds(30);
    DateTime deadline = context.CurrentUtcDateTime.Add(timeout);

    using (var cts = new CancellationTokenSource())
    {
        Task activityTask = context.CallActivityAsync("FlakyFunction");
        Task timeoutTask = context.CreateTimer(deadline, cts.Token);

        Task winner = await Task.WhenAny(activityTask, timeoutTask);
        if (winner == activityTask)
        {
            // success case
            cts.Cancel();
            return true;
        }
        else
        {
            // timeout case
            return false;
        }
    }
}

Примечание

Предыдущие примеры C# предназначены для расширения "Устойчивые функции" версии 2.x. Для расширения "Устойчивые функции" версии 1.x необходимо использовать DurableOrchestrationContext вместо IDurableOrchestrationContext. Дополнительные сведения о различиях между версиями см. в статье Версии устойчивых функций.

Примечание

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

необработанных исключений.

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

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