영어로 읽기

다음을 통해 공유


복원력 있는 앱 개발 소개

복원력이란 일시적인 오류로부터 복구하고 계속해서 작동하도록 하는 앱의 능력을 말합니다. .NET 프로그래밍에서는 복원력을 달성하기 위해 오류를 적절하게 처리하고 신속하게 복구할 수 있는 앱을 디자인합니다. .NET에서 복원력 있는 앱을 빌드하는 데 도움이 되도록 NuGet에서 다음 두 패키지를 사용할 수 있습니다.

NuGet 패키지 설명
📦 Microsoft.Extensions.Resilience 이 NuGet 패키지는 일시적인 오류에 대비하여 앱을 강화하는 메커니즘을 제공합니다.
📦 Microsoft.Extensions.Http.Resilience 이 NuGet 패키지는 특히 HttpClient 클래스에 대한 복원력 메커니즘을 제공합니다.

이 두 NuGet 패키지는 인기 있는 오픈 소스 프로젝트인 Polly를 기반으로 빌드됩니다. Polly는 개발자가 재시도, 회로 차단기, 시간 초과, 격벽 격리, 처리율 제한, 대체, 헤징과 같은 전략을 Fluent 스타일을 통해 스레드로부터 안전한 방식으로 표현할 수 있는 .NET 복원력 및 일시적인 오류 처리 라이브러리입니다.

중요

Microsoft.Extensions.Http.Polly NuGet 패키지는 더 이상 사용되지 않습니다. 대신 앞서 언급한 패키지 중 하나를 사용하세요.

시작하기

.NET에서 복원력 관련 작업을 시작하려면 Microsoft.Extensions.Resilience NuGet 패키지를 설치합니다.

dotnet add package Microsoft.Extensions.Resilience --version 8.0.0

자세한 내용은 dotnet add package 또는 .NET 애플리케이션에서 패키지 종속성 관리를 참조하세요.

복원력 파이프라인 빌드

복원력을 사용하려면 먼저 복원력 기반 전략의 파이프라인을 빌드해야 합니다. 구성된 각 전략은 구성 순서대로 실행됩니다. 즉, 순서가 중요합니다. 진입점은 AddResiliencePipeline이라는 IServiceCollection 형식의 확장 메서드입니다. 이 메서드는 파이프라인의 식별자와 파이프라인을 구성하는 대리자를 사용합니다. 대리자는 파이프라인에 복원력 전략을 추가하는 데 사용되는 ResiliencePipelineBuilder 인스턴스를 전달받습니다.

다음 문자열 기반 key 예제를 살펴보세요.

using Microsoft.Extensions.DependencyInjection;
using Polly;
using Polly.CircuitBreaker;
using Polly.Registry;
using Polly.Retry;
using Polly.Timeout;

var services = new ServiceCollection();

const string key = "Retry-Timeout";

services.AddResiliencePipeline(key, static builder =>
{
    // See: https://www.pollydocs.org/strategies/retry.html
    builder.AddRetry(new RetryStrategyOptions
    {
        ShouldHandle = new PredicateBuilder().Handle<TimeoutRejectedException>()
    });

    // See: https://www.pollydocs.org/strategies/timeout.html
    builder.AddTimeout(TimeSpan.FromSeconds(1.5));
});

앞의 코드가 하는 역할은 다음과 같습니다.

  • ServiceCollection 인스턴스를 만듭니다.
  • 파이프라인을 식별하는 key를 정의합니다.
  • ServiceCollection 인스턴스에 복원력 파이프라인을 추가합니다.
  • 재시도 및 시간 제한 전략을 사용하여 파이프라인을 구성합니다.

각 파이프라인은 지정된 key에 대해 구성되며 각 key는 공급자로부터 파이프라인을 가져올 때 해당 ResiliencePipeline을 식별하는 데 사용됩니다. keyAddResiliencePipeline 메서드의 제네릭 형식 매개 변수입니다.

복원력 파이프라인 작성기 확장

파이프라인에 전략을 추가하려면 ResiliencePipelineBuilder 인스턴스에서 사용 가능한 Add* 확장 메서드 중 하나를 호출합니다.

  • AddRetry: 오류가 발생하면 다시 시도합니다. 문제가 일시적이고 사라질 수 있는 경우에 유용합니다.
  • AddCircuitBreaker: 손상되었거나 사용 중인 경우 시도를 중단합니다. 시간 낭비와 상황 악화를 방지하는 데 도움이 됩니다.
  • AddTimeout: 시간이 너무 오래 걸리면 포기합니다. 리소스가 확보되어 성능이 개선될 수 있습니다.
  • AddRateLimiter: 수락하는 요청 수를 제한합니다. 인바운드 로드를 제어할 수 있습니다.
  • AddConcurrencyLimiter: 요청 수를 제한합니다. 아웃바운드 로드를 제어할 수 있습니다.
  • AddFallback: 오류가 발생하면 다른 작업을 수행합니다. 사용자 환경이 개선됩니다.
  • AddHedging: 대기 시간이 길거나 오류가 발생하는 경우 요청을 여러 번 실행합니다. 응답성을 향상시킬 수 있습니다.

자세한 내용은 복원력 전략을 참조하세요. 예를 보려면 복원력 있는 HTTP 앱 빌드: 주요 개발 패턴을 참조하세요.

메트릭 보강

보강은 이름/값 쌍의 형태를 사용해 잘 알려진 상태로 원격 분석을 자동으로 보강하는 것입니다. 예를 들어 앱은 작업결과 코드를 포함하는 로그를 열로 내보내 일부 작업의 결과를 나타낼 수 있습니다. 이 상황에서 주변 컨텍스트에 따라 보강은 원격 분석 백 엔드로 전송될 때 클러스터 이름, 프로세스 이름, 지역, 테넌트 ID 등을 로그에 추가합니다. 보강이 추가되면 앱 코드는 보강된 메트릭의 이점을 활용하기 위해 추가 작업을 수행할 필요가 없습니다.

보강의 작동 방식

로그 및 메트릭을 생성하는 1,000개의 전역 분산 서비스 인스턴스를 상상해 보세요. 서비스 대시보드에서 문제가 발생하면 문제가 있는 지역 또는 데이터 센터를 신속하게 식별하는 것이 중요합니다. 보강은 메트릭 레코드에 분산 시스템의 오류를 정확히 파악하는 데 필요한 정보가 포함되도록 합니다. 보강이 없으면 앱 코드에 이 상태를 내부적으로 관리하고, 로깅 프로세스에 통합하고, 수동으로 전송해야 하는 부담이 생깁니다. 보강은 이 프로세스를 간소화하여 앱의 논리에 영향을 주지 않고 원활하게 처리합니다.

복원력의 경우 보강을 추가할 때 다음 차원이 나가는 원격 분석에 추가됩니다.

  • error.type: 예외 정보의 하위 카디널리티 버전입니다.
  • request.name: 요청의 이름입니다.
  • request.dependency.name: 종속성의 이름입니다.

내부적으로는 Polly의 원격 분석 MeteringEnricher를 기반으로 복원력 보강이 구축됩니다. 자세한 내용은 Polly: 계량 보강을 참조하세요.

복원력 보강 추가

복원력 파이프라인 등록뿐만 아니라 복원력 보강 등록도 수행할 수 있습니다. 보강을 추가하려면 IServiceCollection 인스턴스에서 AddResilienceEnricher(IServiceCollection) 확장 메서드를 호출합니다.

services.AddResilienceEnricher();

AddResilienceEnricher 확장 메서드를 호출하면 기본 Polly 라이브러리에 내장된 기본 차원 위에 차원이 추가됩니다. 다음 보강 차원이 추가됩니다.

  • IExceptionSummarizer를 기반으로 하는 예외 보강. 원격 측정에 사용할 예외를 요약하는 메커니즘을 제공합니다. 자세한 내용은 예외 요약을 참조하세요.
  • RequestMetadata를 기반으로 하는 요청 메타데이터 보강. 원격 분석에 대한 요청 메타데이터를 보유합니다. 자세한 내용은 Polly: 원격 분석 메트릭을 참조하세요.

복원력 파이프라인 사용

구성된 복원력 파이프라인을 사용하려면 ResiliencePipelineProvider<TKey>에서 파이프라인을 가져와야 합니다. 이전에 파이프라인을 추가했을 때 keystring 형식이었으므로 ResiliencePipelineProvider<string>에서 파이프라인을 가져와야 합니다.

using ServiceProvider provider = services.BuildServiceProvider();

ResiliencePipelineProvider<string> pipelineProvider =
    provider.GetRequiredService<ResiliencePipelineProvider<string>>();

ResiliencePipeline pipeline = pipelineProvider.GetPipeline(key);

앞의 코드가 하는 역할은 다음과 같습니다.

  • ServiceCollection 인스턴스에서 ServiceProvider를 빌드합니다.
  • 서비스 공급자로부터 ResiliencePipelineProvider<string>을 가져옵니다.
  • ResiliencePipelineProvider<string>에서 ResiliencePipeline을 검색합니다.

복원력 파이프라인 실행

복원력 파이프라인을 사용하려면 ResiliencePipeline 인스턴스에서 사용 가능한 Execute* 메서드 중 하나를 호출합니다. ExecuteAsync 메서드에 대한 다음 호출 예를 살펴보세요.

await pipeline.ExecuteAsync(static cancellationToken =>
{
    // Code that could potentially fail.

    return ValueTask.CompletedTask;
});

앞의 코드는 ExecuteAsync 메서드 내에서 대리자를 실행합니다. 오류가 발생하면 구성된 전략이 실행됩니다. 예를 들어 RetryStrategy가 세 번 재시도하도록 구성된 경우 실패가 전파되기 전에 대리자가 네 번(첫 시도 1회 + 재시도 3회) 실행됩니다.

다음 단계