リトライパターン

一時的な障害に対して自動的にリクエストを再試行し、指数バックオフで間隔を調整する設計パターン

耐障害性分散システム

リトライパターンとは

リトライパターンは、ネットワークタイムアウト、サービスの一時的な過負荷、データベースのロック競合など、一時的な障害 (Transient Fault) に対して自動的にリクエストを再試行する設計パターンである。分散システムでは一時的な障害は日常的に発生するため、リトライは必須の設計要素だ。

指数バックオフ + ジッター

リトライ間隔を固定 (1 秒ごと) にすると、障害中のサービスにリクエストが集中し、回復を妨げる (Thundering Herd)。指数バックオフではリトライごとに間隔を倍増させ、ジッターでランダムな揺らぎを加える。

async function withRetry<T>(
  fn: () => Promise<T>,
  maxRetries = 3,
  baseDelay = 1000,
): Promise<T> {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    try {
      return await fn();
    } catch (err) {
      if (attempt === maxRetries) throw err;
      if (!isRetryable(err)) throw err;

      const delay = baseDelay * 2 ** attempt;
      const jitter = Math.random() * delay * 0.5;
      await new Promise(r => setTimeout(r, delay + jitter));
    }
  }
  throw new Error('Unreachable');
}

function isRetryable(err: unknown): boolean {
  if (err instanceof Error && 'statusCode' in err) {
    const code = (err as any).statusCode;
    return code === 429 || code === 503 || code >= 500;
  }
  return true; // ネットワークエラーはリトライ
}
リトライ 1: 1 + ジッター (0〜0.5秒)
リトライ 2: 2 + ジッター (0〜1秒)
リトライ 3: 4 + ジッター (0〜2秒)

リトライすべきケースとすべきでないケース

リトライすべきケースとすべきでないケースを以下に示す。

リトライすべき (一時的)リトライすべきでない (恒久的)
HTTP 429 (Too Many Requests)HTTP 400 (Bad Request)
HTTP 503 (Service Unavailable)HTTP 401 (Unauthorized)
ネットワークタイムアウトHTTP 404 (Not Found)
DB のロック競合バリデーションエラー
DynamoDB の ProvisionedThroughputExceededExceptionビジネスロジックエラー

恒久的なエラーをリトライしても成功しない。リソースを無駄に消費し、障害の回復を遅らせる。

AWS での実装パターン

SQS + Lambda

Lambda が例外をスローすると、SQS がメッセージを自動的にリトライする。maxReceiveCount でリトライ回数を制限し、上限に達したらデッドレターキュー (DLQ) に移動する。

Step Functions

Step FunctionsRetry フィールドで、エラータイプごとにリトライ戦略を定義できる。

{
  "Retry": [{
    "ErrorEquals": ["States.TaskFailed"],
    "IntervalSeconds": 2,
    "MaxAttempts": 3,
    "BackoffRate": 2.0
  }]
}

リトライとべき等性

リトライが安全に動作するには、操作がべき等 (同じ操作を複数回実行しても結果が同じ) である必要がある。PUT /orders/123 は何度実行しても同じ結果だが、POST /orders は実行するたびに新しい注文が作成される。べき等でない操作にはべき等キーを使う。

より深く学ぶには関連書籍が役立つ。

この記事は役に立ちましたか?

関連用語

関連する記事