リトライパターン
一時的な障害に対して自動的にリクエストを再試行し、指数バックオフで間隔を調整する設計パターン
リトライパターンとは
リトライパターンは、ネットワークタイムアウト、サービスの一時的な過負荷、データベースのロック競合など、一時的な障害 (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 Functions の Retry フィールドで、エラータイプごとにリトライ戦略を定義できる。
{
"Retry": [{
"ErrorEquals": ["States.TaskFailed"],
"IntervalSeconds": 2,
"MaxAttempts": 3,
"BackoffRate": 2.0
}]
}
リトライとべき等性
リトライが安全に動作するには、操作がべき等 (同じ操作を複数回実行しても結果が同じ) である必要がある。PUT /orders/123 は何度実行しても同じ結果だが、POST /orders は実行するたびに新しい注文が作成される。べき等でない操作にはべき等キーを使う。
より深く学ぶには関連書籍が役立つ。
この記事は役に立ちましたか?
関連用語
指数バックオフ
リトライ間隔を指数関数的に増加させ、障害時のシステム負荷を軽減するリトライ戦略
デッドレターキュー
処理に失敗したメッセージを退避させ、後から調査・再処理するためのキュー
Webhook
イベント発生時にサーバーが指定された URL に HTTP リクエストを送信する、プッシュ型の通知メカニズム
べき等キー
API リクエストの重複実行を防ぐために、クライアントが付与する一意な識別子
サーキットブレーカーライブラリ
外部サービスの障害を検知し、自動的にリクエストを遮断して障害の連鎖を防ぐライブラリ
HTTP ステータスコード
HTTP レスポンスの結果を 3 桁の数値で表す標準コードで、1xx〜5xx の 5 カテゴリに分類される
関連する記事
障害対応の夜に思い出す、あの本の 1 ページ
本番障害の緊迫した場面で、過去に読んだ技術書の知識が助けてくれた経験はありませんか。「いつか役立つ」知識が「今この瞬間」に変わる読書の価値を考えます。
エラーメッセージを読めるエンジニアは何が違うのか
エラーが出たときに冷静に原因を特定できる人と、パニックになる人。その差は経験だけでなく、読んできた本の種類にあります。デバッグ力を支える読書の傾向を分析します。
深夜 3 時のデプロイ前に読み返したい 1 ページ
本番デプロイの直前、最終確認のチェックリストとして技術書の特定のページが役立つことがあります。緊張の場面で頼りになる「お守りの 1 ページ」の見つけ方と活用法。