Polly를 영어로 사용하는 방법그물

30463 단어 dotnetcoredotnetpolly
본문에서, 나는 Polly가 제공한 도구 모음과 그것을 사용하는 몇 가지 좋은 방법과 나쁜 방법을 묘사하고 싶다.당신이 탄력성과 오류 코드를 더욱 잘 이해할 수 있기를 바랍니다.


폴리에 관한 몇 마디

Polly is a .NET resilience and transient-fault-handling library that allows developers to express policies such as Retry, Circuit Breaker, Timeout, Bulkhead Isolation, and Fallback in a fluent and thread-safe manner.



이야기를 차단기부터 시작하도록 하겠습니다.
회로 차단기라는 매우 유용한 탄력성 모드로 시작하였습니다.

Handle faults that might take a variable amount of time to recover from when connecting to a remote service or resource. This can improve the stability and resiliency of an application.


이 말은 차단기의 작용을 명확하게 설명하지 않았다.나는 간단한 예로 그것이 어떻게 일을 하는지 묘사하고 싶다.우리는 날씨에 대한 정보를 제공하는 API와 통합해야 하는데, 이 날씨는 API가 우리 소유가 아니다.타사 API를 사용하면 다른 API가 충돌하는 상황을 생각할 수 있습니다.타사 API가 다운된 이유와 사용 가능한 시점을 알 수 없습니다.프로세스의 경우 작업 결과가 시간 초과될 때까지 기다리지 않고 작업을 수행하지 않는 API로 요청을 건너뛰는 것이 좋습니다.회로 차단기는 이 게임에 매우 적합하다.스트림이 중단되고 일정 시간 동안 API 손상을 방지하는 요청이 발생합니다.

우리 는 몇 가지 예 를 깊이 이해합시다
public static async Task BasicAsync()
{
        var circuitBreakerPolicy = Policy
        .Handle<Exception>()
        .CircuitBreakerAsync(2, TimeSpan.FromSeconds(1));

    // 2 errors break it for 1 second 

    for (int i = 0; i < 10; ++i)
    {
        try
        {
            Console.WriteLine($"Execution {i}");
            await circuitBreakerPolicy.ExecuteAsync(async () =>
            {
                Console.WriteLine($"before throw exception {i}");
                throw new Exception($"Error {i}");
            });
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Catch ex {ex.Message}");
        }

        await Task.Delay(500);
    }
}
이 예에서 차단기는 두 번의 이상 후에 켜지고 1초 안에 켜진 다음 다시 오류를 얻을 수 있도록 합니다.이것은 매우 명확한 예로 그것이 어떻게 일을 하는지 설명한다.다른 시스템은 다시 사용할 수 있도록 두 번째로 중단되었다.
다음은 회로 차단기의 복잡한 구성입니다.
public static async Task AdvancedAsync()
{
    var advancedCircuitBreaker = Policy
        .Handle<Exception>()
        .AdvancedCircuitBreakerAsync(0.5, TimeSpan.FromSeconds(2), 3, TimeSpan.FromSeconds(1));

    for (int i = 0; i < 10; i++)
    {
        try
        {
            Console.WriteLine($"Execution {i}");
            await advancedCircuitBreaker.ExecuteAsync(async () =>
            {
                Console.WriteLine($"before throw exception {i}");
                throw new Exception($"Error {i}");
            });
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Catch ex {ex.Message}");
        }

        await Task.Delay(500);
    }
}
우리는 일부 오류만이 아니라 더 복잡한 방식으로 차단기를 설정할 수 있다.우리는 요청의 50% 가 2초 안에 오류를 던지고, 최소 요청량이 3이면 열어야 한다고 규정하고 있다.
이 두 가지 예는 모두 효과가 있기 때문에 우리는 어떤 배치가 우리에게 더 적합한지 결정할 책임이 있다.

시간 초과 정책 및 정책 패키지
Polly가 제공하는 또 다른 유용한 전략은 시간 초과입니다.이 한도값을 초과하면 시간 초과 정책이 호출을 강제로 멈추고 오류를 던질 수 있는지 확인합니다.
다음 예에서 시간 초과 오류를 일으키는 시간 초과 정책과 차단기 정책을 결합시켜 차단기 정책이 100% 또는 마지막 3초 안에 오류를 실행하는 것을 방지하고 싶습니다.
public static async Task TimeoutConsequenceAsync()
{
    var advancedCircuitBreaker = Policy
        .Handle<Exception>()
        .AdvancedCircuitBreakerAsync(1, TimeSpan.FromSeconds(3), 2, TimeSpan.FromSeconds(1));

    var timeoutPolicy = Policy.TimeoutAsync(TimeSpan.FromMilliseconds(1000), TimeoutStrategy.Pessimistic);
    // note: Optimistic cancel operation via cancellation token 

    var wrapPolicy = Policy.WrapAsync(advancedCircuitBreaker, timeoutPolicy);

    for (int i = 0; i < 10; i++)
    {
        try
        {
            Console.WriteLine($"Execution {i}");
            await wrapPolicy.ExecuteAsync(async () =>
            {
                Console.WriteLine($"before throw exception {i}");
                await Task.Delay(TimeSpan.FromMilliseconds(1000));
                Console.WriteLine($"after throw exception {i}");
            });
            Console.WriteLine($"Execution {i} after actual call");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Catch ex {ex.Message}");
        }

        await Task.Delay(100);
    }
}
코드가 최대 1초까지 실행될 수 있도록 시간 초과 정책을 만들었습니다. 비관적인 상황에서 시간 초과 정책은 이상을 일으킬 수 있습니다.낙관적인 정책을 선택할 경우 시간 초과 정책에 의존하는 CancelationToken으로 코드를 구성해야 합니다.
또한 두 가지 전략을 하나의 복잡한 전략으로 조합하는 전략도 사용합니다.경찰
wrap 호출에서 코드를 터치하는 정책을 더 정확한 위치에 두어야 한다는 것을 기억하면 도움이 될 것입니다.상기 예시에서 시간 초과 정책 포장 코드, 회로 정책 포장 시간 초과 정책.
위의 예시를 실행하면 코드가 두 번 실행되고 실패합니다. 시간 초과 정책 차단기가 한도값에 도달하고 1초 동안 열기로 결정한 다음에 시간 초과 정책을 다시 터치하고 회로가 다시 열기 상태로 들어가기 때문입니다.
동시에 작업을 열면 어떻게 되는지 살펴보겠습니다.
public static async Task TimeoutRandomParallelAsync(){
  var advancedCircuitBreaker = Policy
      .Handle<Exception>()
      .AdvancedCircuitBreakerAsync(1, TimeSpan.FromSeconds(3), 2, TimeSpan.FromSeconds(1));

  var timeoutPolicy = Policy.TimeoutAsync(TimeSpan.FromMilliseconds(1000), TimeoutStrategy.Pessimistic);
  // note: Optimistic cancel operation via cancellation token 

  var wrapPolicy = Policy.WrapAsync(advancedCircuitBreaker, timeoutPolicy);

  var tasks = new List<Task>();
  for (int i = 0; i < 10; i++)
  {
      try
      {
          tasks.Add(wrapPolicy.ExecuteAsync(async () =>
          {
              Console.WriteLine($"before throw exception {i}");
              await Task.Delay(TimeSpan.FromMilliseconds(3500));
          }));
      }
      catch (Exception ex)
      {
          // never come here
          Console.WriteLine($"Catch ex {ex.Message}");
      }

      // without delay all tasks started invocation and circuit breaker doesn`t know about fails 
      await Task.Delay(100);
  }

  try
  {
      await Task.WhenAll(tasks);
  }
  catch (Exception ex)
  {
      // here ex contains first error thrown by list of tasks
      var errors = tasks.Select(t => t.Exception);

      foreach (var error in errors)
      {
          Console.WriteLine($"HERE WE COME {error.Message}");
      }
  }
}
이 예에서, 우리는 10개의 임무를 만들고, 그것들이 완성되기를 기다렸다.이런 예에서 차단기는 게임에 들어가지 않았고, 우리는 10개의 시간 초과 이상을 얻었다.차단기는 다른 요청이 오류를 일으키기 전에 요청을 통과합니다.
이 예는 현실 세계에서 많은 요청이 우리 프로그램에 오면 차단기가 끊어진 부분에 부딪힐 때 어떤 일이 일어나는지 보여줄 수 있지만, 한도값이 끊어진 후에 다음 요청은 끊어진 차단기에 직면하게 된다.

회로가 열릴 때 어떻게 해야 합니까?
Polly는 예비(fallback) 정책을 사용하여 오류를 쉽게 처리할 수 있는 방법을 제공합니다.예비(fallback) 정책을 사용하여 이전 예제를 구체화합니다.
public static async Task FallbackWithTimeoutAsync()
{
    var advancedCircuitBreaker = Policy
        .Handle<Exception>()
        .AdvancedCircuitBreakerAsync(0.5, TimeSpan.FromSeconds(2), 3, TimeSpan.FromSeconds(1));

    var timeoutPolicy = Policy.TimeoutAsync(TimeSpan.FromMilliseconds(1000), TimeoutStrategy.Pessimistic);

    var fallback = Policy
        .Handle<BrokenCircuitException>()
        .Or<TimeoutException>()
        .Or<AggregateException>()
        .Or<TimeoutRejectedException>()
        .FallbackAsync((cancellation) =>
        {
            Console.WriteLine("Fallback action");
            return Task.CompletedTask;
        });

    var wrapPolicy = Policy.WrapAsync(fallback ,advancedCircuitBreaker, timeoutPolicy);

    var tasks = new List<Task>();
    for (int i = 0; i < 10; i++)
    {
        try
        {
            tasks.Add(wrapPolicy.ExecuteAsync(async () =>
            {
                Console.WriteLine($"before wait {i}");
                await Task.Delay(TimeSpan.FromMilliseconds(3500));
                Console.WriteLine($"after wait {i}");
            }));
        }
        catch (AggregateException ex)
        {
            // never come here
            Console.WriteLine($"Catch ex {ex.Message}");
        }

        await Task.Delay(500);
    }

    try
    {
        await Task.WhenAll(tasks);
    }
    catch (AggregateException ex)
    {
        // here ex contains first error thrown by list of tasks
        var errors = tasks.Where(t=> t.Exception != null).Select(t => t.Exception);

        foreach (var error in errors)
        {
            Console.WriteLine($"ERROR is {error.Message} {error.GetType()}");
        }

    }
}
일련의 예외 유형을 처리하고 이 경우 예비(fallback) 정책을 제공하는 예비(fallback) 정책을 만들었습니다.정책이 실행되는 동안 예비(fallback)을 가장 왼쪽에 있는 정책으로 지정해야 합니다.소포 수술.

그럼 다시 해볼까요?
개발자로서 우리는 전략을 조심스럽게 재시도해야 한다.이것은 원가의 급등을 초래할 수도 있고, 심지어는 당신의 집단을 죽일 수도 있다.Polly는 재시도를 구성하는 방법에 대한 좋은 예 목록을 가지고 있습니다.다시 시도 정책을 만들어야 한다면 지수 지연과 제한된 횟수로 설정하는 것이 좋다는 것을 강조하고 싶습니다.

결론
회로 차단기는 분포식 시스템을 처리할 때 반드시 사용해야 하는 모드이다.개발자로서 시스템의 어떤 부분이 작용하지 않을 때, 당신은 이러한 상황에 주의해야 합니다. 이곳의 반환 전략은 매우 적합합니다.또 외부 통화를 최대한 시간 초과로 제한하고 기다리는 것을 좋아하는 사람은 없다.
무슨 문제나 의견이 있습니까?LinkedIn에서 Ping 을 하거나 아래에 설명합니다.만약 당신이 이 글을 좋아한다면 박수를 치며 모든 친구들과 나누세요.
트위터:
영영:
자세한 내용은 다음을 참조하십시오.
https://blog.akyltech.com/

좋은 웹페이지 즐겨찾기