0Pricing
C# Academy · 강의

복원력 기초: 재시도와 백오프

지수 백오프와 지터를 적용한 간단한 재시도를 구현하고, 일시적 오류와 치명적 오류를 구분하며, 지연 시간을 제한하고, 취소되면 중지합니다.

복원력 기초: 재시도와 백오프은(는) CoddyKit의 무료 C# Academy 강의입니다. 이것은 3개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 C# Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. C# Academy 강의에는 총 3개의 강의가 포함되어 있습니다.

재시도와 백오프가 필요한 이유

목표: 호출을 견고하게 만듭니다.

  • 일시적 실패를 재시도합니다
  • 지수형 백오프와 지터를 사용합니다
  • 최대 시도 횟수와 최대 지연 시간을 설정합니다
  • 치명적 오류나 취소가 발생하면 중지합니다

실패 분류

일시적: 시간 제한, 429/5xx 응답, 일시적인 네트워크 문제입니다.

치명적: 잘못된 요청, 인증되지 않은 요청, 유효성 검사 오류이며 재시도하지 않습니다.

규칙: 나중에 성공할 수 있는 경우에만 재시도합니다.

백오프 도우미

간단한 도우미가 시도할 때마다 지연 시간을 늘리고 작은 지터를 추가합니다. 또한 최대 지연 시간을 제한합니다.

using System;
using System.Threading;
using System.Threading.Tasks;

public static class Backoff
{
  // Compute delay = min(base * 2^attempt, cap) + jitter
  public static int ComputeDelayMs(int attempt, int baseMs, int capMs, int jitterMs, Random rng)
  {
    long exp = (long)baseMs << attempt; // base * 2^attempt
    if (exp > capMs) exp = capMs;
    int jitter = rng.Next(0, jitterMs + 1); // [0..jitterMs]
    return (int)exp + jitter;
  }
}

public class Program
{
  public static void Main(string[] args)
  {
    Random rng = new Random(123);
    for (int i = 0; i < 5; i++)
    {
      int d = Backoff.ComputeDelayMs(i, 100, 2000, 50, rng);
      Console.WriteLine("Attempt " + i + " -> " + d + " ms");
    }
  }
}

재시도 래퍼

호출을 감쌉니다. 일시적 예외만 재시도하고 다른 예외가 발생하면 중지합니다. 재시도할 때마다 지터를 포함해 더 오래 기다립니다.

using System;
using System.Threading;
using System.Threading.Tasks;

public class Program
{
  static readonly Random Rng = new Random();

  // Simulate an operation that sometimes fails transiently.
  static async Task<string> FlakyAsync()
  {
    await Task.Delay(60);
    // 50% chance of transient failure
    if (DateTime.UtcNow.Ticks % 2 == 0) throw new TimeoutException("Transient");
    return "OK";
  }

  static async Task<T> RetryAsync<T>(Func<Task<T>> action, int maxAttempts)
  {
    int baseMs = 100, capMs = 2000, jitterMs = 50;
    for (int attempt = 0; attempt < maxAttempts; attempt++)
    {
      try
      {
        return await action();
      }
      catch (TimeoutException)
      {
        if (attempt == maxAttempts - 1) throw; // out of retries
        int delay = Backoff.ComputeDelayMs(attempt, baseMs, capMs, jitterMs, Rng);
        await Task.Delay(delay);
      }
      catch (Exception)
      {
        // Non-transient (unknown) -> do not retry
        throw;
      }
    }
    throw new InvalidOperationException("Unreachable");
  }

  public static void Main(string[] args)
  {
    try
    {
      string s = RetryAsync(FlakyAsync, 5).GetAwaiter().GetResult();
      Console.WriteLine("Result: " + s);
    }
    catch (Exception ex)
    {
      Console.WriteLine("Failed: " + ex.GetType().Name);
    }
  }
}

예산이 있는 재시도

취소를 통해 전체 시간 예산을 추가합니다. 작업과 백오프 지연 모두에 토큰을 전달합니다.

using System;
using System.Threading;
using System.Threading.Tasks;

public static class RetryUtil
{
  static readonly Random Rng = new Random();

  public static async Task<T> RetryAsync<T>(Func<CancellationToken, Task<T>> action, int maxAttempts, CancellationToken ct)
  {
    int baseMs = 100, capMs = 1500, jitterMs = 50;
    for (int attempt = 0; attempt < maxAttempts; attempt++)
    {
      ct.ThrowIfCancellationRequested();
      try
      {
        return await action(ct);
      }
      catch (TimeoutException)
      {
        if (attempt == maxAttempts - 1) throw;
        int delay = Backoff.ComputeDelayMs(attempt, baseMs, capMs, jitterMs, Rng);
        await Task.Delay(delay, ct); // pass token so we can abort waiting
      }
    }
    throw new InvalidOperationException("Unreachable");
  }
}

public class Program
{
  static async Task<string> SometimesSlowAsync(CancellationToken ct)
  {
    await Task.Delay(200, ct);
    if (DateTime.UtcNow.Millisecond % 3 != 0) throw new TimeoutException("Transient");
    return "OK";
  }

  public static void Main(string[] args)
  {
    var cts = new CancellationTokenSource();
    cts.CancelAfter(800); // overall budget

    try
    {
      string s = RetryUtil.RetryAsync(SometimesSlowAsync, 5, cts.Token).GetAwaiter().GetResult();
      Console.WriteLine("Done: " + s);
    }
    catch (OperationCanceledException) { Console.WriteLine("Canceled"); }
    catch (Exception ex) { Console.WriteLine("Failed: " + ex.Message); }
  }
}

지침

팁:

  • 멱등성이 있는 호출만 재시도합니다.
  • 시도 횟수와 지연 시간에 상한을 둡니다.
  • 동시 폭주를 방지하려면 작은 지터를 추가합니다.
  • 최종 실패를 이유와 시도 횟수와 함께 기록합니다.

백오프 정의

간단히 확인해 보겠습니다. 지터를 포함한 지수형 백오프를 가장 잘 설명하는 것은 무엇입니까?

요약

요약: 일시적 오류만 재시도하고, 지연 시간을 상한까지 지수적으로 늘리며, 지터를 추가하고, 취소나 치명적 오류가 발생하면 중지합니다.

자주 묻는 질문

“복원력 기초: 재시도와 백오프” 강의는 무료인가요?

네 — “복원력 기초: 재시도와 백오프” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 C# Academy 강의 전체를 잠금 해제할 수 있습니다. C# Academy 강의에는 총 3개의 강의가 포함되어 있습니다.

“복원력 기초: 재시도와 백오프”에서 뭘 배우나요?

지수 백오프와 지터를 적용한 간단한 재시도를 구현하고, 일시적 오류와 치명적 오류를 구분하며, 지연 시간을 제한하고, 취소되면 중지합니다. 브라우저에서 직접 실행하는 실습 코드로 C# Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

C# Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 C# Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 3개 중 3번째 강의입니다.

“복원력 기초: 재시도와 백오프” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 C# Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 C# Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. CancellationToken 패턴과 협력적 취소
  2. 시간 제한, IProgress , 비동기 삭제(에뮬레이션)
  3. 복원력 기초: 재시도와 백오프
← C# Academy(으)로 돌아가기