サーキットブレーカーライブラリ
外部サービスの障害を検知し、自動的にリクエストを遮断して障害の連鎖を防ぐライブラリ
設計パターン耐障害性
サーキットブレーカーライブラリとは
サーキットブレーカーは、外部サービスの障害を検知し、一定回数の失敗後にリクエストを自動的に遮断するパターンである。電気のブレーカーと同じ原理で、障害の連鎖 (カスケード障害) を防ぐ。
3 つの状態
Closed (正常) → 失敗が閾値を超える → Open (遮断)
↓ タイムアウト後
Half-Open (試行)
↓ 成功 → Closed
↓ 失敗 → Open
| 状態 | 動作 |
|---|---|
| Closed | リクエストを通す、失敗をカウント |
| Open | リクエストを即座に拒否 (外部サービスに送らない) |
| Half-Open | 少数のリクエストを試行し、回復を確認 |
TypeScript での実装
class CircuitBreaker {
private failures = 0;
private state: 'closed' | 'open' | 'half-open' = 'closed';
private nextRetry = 0;
constructor(private threshold = 5, private timeout = 30000) {}
async call<T>(fn: () => Promise<T>): Promise<T> {
if (this.state === 'open') {
if (Date.now() < this.nextRetry) throw new Error('Circuit is open');
this.state = 'half-open';
}
try {
const result = await fn();
this.reset();
return result;
} catch (error) {
this.failures++;
if (this.failures >= this.threshold) {
this.state = 'open';
this.nextRetry = Date.now() + this.timeout;
}
throw error;
}
}
private reset() { this.failures = 0; this.state = 'closed'; }
}
Lambda は実行環境が再利用されるため、同一インスタンス内ではサーキットブレーカーの状態が保持される。
リトライとの組み合わせ
リクエスト → リトライ (3回) → 全て失敗 → サーキットブレーカーが Open
→ 以降のリクエストは即座に 503 を返す (外部サービスに負荷をかけない)
→ 30秒後に Half-Open → 1件試行 → 成功 → Closed
AWS での代替手段
AWS ではサーキットブレーカーライブラリの代わりに、Step Functions のリトライ + Catch でエラーハンドリングを行ったり、API Gateway のタイムアウト設定を活用したり、App Mesh の Envoy プロキシでサーキットブレーカーを実現できる。
実務での活用方法は関連書籍にも詳しい。