지속성 함수의 오류 처리(Azure Functions)

Durable Function 오케스트레이션은 코드로 구현되며, 프로그래밍 언어의 기본 제공 오류 처리 기능을 사용할 수 있습니다. 오케스트레이션에 오류 처리 및 보정을 추가하는 데 필요한 새로운 개념은 없습니다. 그러나 알고 있어야 하는 몇 가지 동작이 있습니다.

참고 항목

Azure Functions용 Node.js 프로그래밍 모델 버전 4가 일반 공급됩니다. 새로운 v4 모델은 JavaScript 및 TypeScript 개발자에게 보다 유연하고 직관적인 환경을 제공하도록 설계되었습니다. 마이그레이션 가이드에서 v3과 v4의 차이점에 대해 자세히 알아봅니다.

다음 코드 조각에서 JavaScript(PM4)는 새로운 환경인 프로그래밍 모델 V4를 나타냅니다.

작업 함수의 오류

작업 함수에서 throw되는 모든 예외는 오케스트레이터 함수에 다시 마샬링되고 FunctionFailedException으로 throw됩니다. 오케스트레이터 함수에서 요구 사항에 적합한 오류 처리 및 보정 코드를 작성할 수 있습니다.

예를 들어 한 계정에서 다른 계정으로 자금을 이체하는 다음 오케스트레이터 함수를 살펴보세요.

[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# 예제는 Durable Functions 2.x에 대한 것입니다. Durable Functions 1.x의 경우 IDurableOrchestrationContext 대신 DurableOrchestrationContext를 사용해야 합니다. 버전 간 차이점에 관한 자세한 내용은 Durable Functions 버전 문서를 참조하세요.

첫 번째 CreditAccount 함수 호출이 실패하면 오케스트레이터 함수는 자금을 원본 계정에 다시 크레딧하여 보정합니다.

실패 시 자동 다시 시도

작업 함수 또는 하위 오케스트레이션 함수를 호출할 때 자동으로 다시 시도하는 정책을 지정할 수 있습니다. 다음 예제에서는 함수를 최대 3회 호출하려고 하고 각각의 다시 시도 간에 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# 예제는 Durable Functions 2.x에 대한 것입니다. Durable Functions 1.x의 경우 IDurableOrchestrationContext 대신 DurableOrchestrationContext를 사용해야 합니다. 버전 간 차이점에 관한 자세한 내용은 Durable Functions 버전 문서를 참조하세요.

이전 예제의 작업 함수 호출은 자동 재시도 정책을 구성하기 위한 매개 변수를 사용합니다. 자동 재시도 정책을 사용자 지정하기 위한 몇 가지 옵션이 있습니다.

  • 최대 시도 횟수: 최대 시도 횟수입니다. 1로 설정하면 다시 시도하지 않습니다.
  • 첫 번째 다시 시도 간격: 첫 번째 다시 시도를 수행할 때까지 기다리는 시간입니다.
  • 백오프 계수: 백오프의 증가율을 결정하는 데 사용되는 계수입니다. 기본값은 1입니다.
  • 최대 다시 시도 간격: 다시 시도 간에 기다리는 최대 시간입니다.
  • 다시 시도 시간 제한: 다시 시도하는 데 소요되는 최대 시간입니다. 기본 동작은 무기한으로 다시 시도하는 것입니다.

사용자 지정 재시도 처리기

.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# 예제는 Durable Functions 2.x에 대한 것입니다. Durable Functions 1.x의 경우 IDurableOrchestrationContext 대신 DurableOrchestrationContext를 사용해야 합니다. 버전 간 차이점에 관한 자세한 내용은 Durable Functions 버전 문서를 참조하세요.

참고 항목

이 메커니즘은 실제로 진행 중인 작업 함수 실행을 종료하지 않습니다. 대신 단순히 오케스트레이터 함수를 사용하여 결과를 무시하고 계속 진행할 수 있습니다. 자세한 내용은 타이머 설명서를 참조하세요.

처리되지 않은 예외

처리되지 않은 예외로 인해 오케스트레이터 함수가 실패하면 예외 정보가 자세히 기록되고 인스턴스가 Failed 상태로 완료됩니다.

다음 단계