[C#] Polly Nuget 패키지 - PolicyWrap
- C#
- 2022. 4. 20. 19:46
참조
PolicyWrap 란
- PolicyWrap 이란, 이전에 정의된 정책들을 여러가지 결합된 정책 전략을 의미합니다.
- 예를 들어, Retry 전략이 있고, Timeout 전략이 있을 경우 Retry 전략과 Timeout 전략을 합쳐서 사용하는 것을 의미합니다.
- 그럼 예제를 통해서 PolicyWrap 를 알아 보도록 하겠습니다.
PolicyWrap Syntax
- Polly 공식 문서에서 PolicyWrap 사용 예제 방법은 다음과 같습니다.
- 아래 방식을 이용하여 시나리오를 구성하고, 직접 2개 이상의 전략을 Wrapping 해보겠습니다.
// Define a combined policy strategy, built of previously-defined policies.
var policyWrap = Policy
.Wrap(fallback, cache, retry, breaker, timeout, bulkhead);
// (wraps the policies around any executed delegate: fallback outermost ... bulkhead innermost)
policyWrap.Execute(...)
// Define a standard resilience strategy ...
PolicyWrap commonResilience = Policy.Wrap(retry, breaker, timeout);
// ... then wrap in extra policies specific to a call site, at that call site:
Avatar avatar = Policy<UserAvatar>
.Handle<FooException>()
.Fallback<Avatar>(Avatar.Blank)
.Wrap(commonResilience)
.Execute(() => { /* get avatar */ });
// Share commonResilience, but wrap different policies in at another call site:
Reputation reps = Policy
.Handle<FooException>()
.Fallback<Reputation>(Reputation.NotAvailable)
.Wrap(commonResilience)
.Execute(() => { /* get reputation */ });
시나리오
C# 으로 gRPC Server/Client 서비스를 생성하고 간단하게 로직을 구현합니다.
여기서, Client 에서 Server 의 접속 정보를 다르게 하여
RpcException
이 발생하도록 합니다.실제
RpcException
에러가 발생 하였을 때, Polly 가RpcException
에러를 감지하고 실제로 Timeout을 진행하는지 테스트 진행합니다.
Polly NuGet Package 설치
- 먼저, C# Project 에 Polly NuGet Package 설치 진행합니다.
PMC 명령어 설치
- NuGet Package Manager Command 로 설치할 경우, 다음 명령어로 설치 진행 가능합니다.
Install-Package Polly
NuGet Package 설치
Polly
검색후, 다음 아이콘으로 생긴 NuGet 을 설치 진행합니다.참고로, Polly 는 gRPC 프로젝트에서 Client 프로젝트에 설치 하였습니다. 저는 Client 에서 Server 의 접속이 끊어졌을 경우 테스트 하였기 때문에 Polly 패키지를 Client에 추가하였습니다.
Server 프로젝트 생성
- gRPC Server 프로젝트는
ASP.NET Core gRPC 서비스
프로젝트로 생성하였습니다. ASP.NET Core gRPC 서비스
프로젝트를 생성하게 되면, 기본으로Protos
파일이 생성이 되고, 해당 디렉토리 안에greet.proto
파일이 생성됩니다.- 또한,
GreeterService.cs
클래스가 자동으로 생성되며, 해당 클래스 안에는 gRPC 서버 로직이 구현되어 있습니다. - 해당 프로젝트 생성 과정은 생략 하도록 하겠습니다.
Client 프로젝트 생성
- Client 프로젝트는
콘솔 프로젝트
로 생성하였습니다. - 그리고 다음 3가지의 NuGet Package 를 설치 하였습니다.
- Google.Protobuf
- Grpc.Net.Client
- Grpc.Tools
- 위 3개의 NuGet Package를 설치 진행 되어야 gRPC 통신을 진행할 수 있습니다.
Client 에서 policyWrap 내용 추가
- 앞서, gRPC Client 프로젝트를 추가하였습니다.
- 다음으로, 실제 gRPC Server 에 연결하여 메시지를 보내는 코드를 추가하겠습니다.
- 아래 코드에서는 총 2개의 정책을 추가하였습니다.
- 첫 번째 정책은 retry 정책이고, 두 번째 정책은 timeout 정책입니다.
- 그리고 2개의 정책을
WrapAsync
을 통해서 Wrapping 해주고 있습니다. - 아래 예제 코드는, retry 시도하는 로직이 특정 초(현재 예제 코드에서는 2초) 이상이 걸리는 경우 Timeout 발생하여 그대로 프로그램을 종료할 수 있게 해주는 예제코드입니다.
using Grpc.Core;
using Grpc.Net.Client;
using gRPCService;
using Polly;
using Polly.Timeout;
// Retry 정책
var retryPolly = Policy
.Handle<RpcException>()
.RetryAsync(3, (exception, retryCount, context) =>
{
Console.WriteLine($"try: {retryCount}, Exception: {exception.Message}");
});
// Timeout 정책
var timeoutPolicy = Policy
.TimeoutAsync(TimeSpan.FromSeconds(2), TimeoutStrategy.Pessimistic,
async (context, timespan, task) =>
{
// Add extra logic to be invoked when a timeout occurs, such as logging
Console.WriteLine($"Retry 중 Timeout 발생");
});
var policyWrap = retryPolly.WrapAsync(timeoutPolicy);
var result = await policyWrap.ExecuteAsync(async () => await DoSomething());
/// <summary>
/// gRPC Server 에게 메시지 보내기
/// </summary>
static async Task<string> DoSomething()
{
Console.WriteLine($"{nameof(DoSomething)} has been called.");
var channel = GrpcChannel.ForAddress("https://localhost:7243");
var greeterClient = new Greeter.GreeterClient(channel);
var greeterRequest = new HelloRequest { Name = "Beom" };
var greeter = await greeterClient.SayHelloAsync(greeterRequest);
Console.WriteLine($"{greeter.Message}");
Console.WriteLine($"Successfully send request");
return greeter.Message;
}
실행 결과
- 실행 결과, 첫 번째 Retry 하는 중에 2초 이상의 로직 시간이 소요되어 그 안에서 2번째 정책인 Timeout 정책이 발효되어
Retry 중 Timeout 발생
메시지 출력과 함께 프로그램이 그대로 에러를 발생시켜 종료하는 것을 확인할 수 있습니다.
DoSomething has been called.
Retry 중 Timeout 발생
728x90
'C#' 카테고리의 다른 글
[C#] Fluent Validation 이란? (0) | 2022.04.21 |
---|---|
[C#] Polly Nuget 패키지 - Bulkhead Isolation, Rate-Limit (0) | 2022.04.20 |
[C#] Polly Nuget 패키지 - Timeout (0) | 2022.04.19 |
[C#] Polly Nuget 패키지 - Fallback (0) | 2022.04.19 |
[C#] Polly Nuget 패키지 - Circuit Breaker (0) | 2022.04.18 |
이 글을 공유하기