복원력 기초: 재시도와 백오프
지수 백오프와 지터를 적용한 간단한 재시도를 구현하고, 일시적 오류와 치명적 오류를 구분하며, 지연 시간을 제한하고, 취소되면 중지합니다.
복원력 기초: 재시도와 백오프은(는) 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 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- CancellationToken 패턴과 협력적 취소
- 시간 제한, IProgress , 비동기 삭제(에뮬레이션)
- 복원력 기초: 재시도와 백오프