resilience-patterns について
resilience-patterns は、.NET の同期呼び出しと非同期メッセージハンドラーの耐障害性設計・監査を支援するスキルです。Polly と Brighter のガイドに加え、コードベースの監査レポートを作成できます。
主な機能
- 01HTTP の耐障害性に関する Polly ガイド
- 02メッセージ処理向け Brighter ガイド
- 03リトライ、サーキットブレーカー、タイムアウト、フォールバック
- 04デッドレターキューのガイド
- 05優先度付き提案を含むコード監査
活用シーン
- 01HTTP クライアントへの耐障害性ポリシー追加
- 02外部サービスのリトライとサーキットブレーカーの設計
- 03リトライとデッドレターキューによる失敗メッセージ処理
- 04コードベースの耐障害性不足の監査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ melodic-software/ claude-code-plugins --skill resilience-patternsインストール後、Claude Code で/resilience-patternsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/brighter-resilience.mdcircuit-breaker-config.mddlq-patterns.mdpolly-patterns.mdretry-strategies.md詳細
レジリエンスパターンのスキル
概要
このスキルでは、.NET アプリケーションにレジリエンスパターンを実装する方法について説明します。Polly を使用した同期レジリエンス(HTTP クライアント、サービス呼び出し)と、Brighter を使用した非同期レジリエンス(メッセージハンドラー)の両方を扱います。
主要な原則: 障害を前提に設計します。システムは一時的な障害に適切に対処し、連鎖障害を防ぎ、有用なフォールバック動作を提供する必要があります。
このスキルを使用するタイミング
キーワード: レジリエンス、サーキットブレーカー、リトライ、polly、brighter、フォールトトレランス、一時的な障害、DLQ、デッドレターキュー、タイムアウト、バルクヘッド、フォールバック、HTTP クライアントのレジリエンス
このスキルは、次の場合に使用します:
- HTTP クライアントのレジリエンスを実装する
- 一時的な障害に対するリトライポリシーを設定する
- 連鎖障害を防ぐサーキットブレーカーを設定する
- メッセージハンドラーのエラー処理を設計する
- デッドレターキューのパターンを実装する
- サービス呼び出しにタイムアウトポリシーを追加する
- バルクヘッド分離を設定する
レジリエンス戦略の概要
同期レジリエンス(Polly)
HTTP 呼び出しと同期サービス通信向け:
| パターン | 目的 | 使用するタイミング |
|---|---|---|
| リトライ | 失敗した操作を再試行する | 一時的な障害(ネットワーク、503、タイムアウト) |
| サーキットブレーカー | 失敗しているサービスへの呼び出しを停止する | 繰り返しの障害からサービス停止が疑われる場合 |
| タイムアウト | 操作時間に上限を設ける | 無期限の待機を防ぐ |
| バルクヘッド | 障害を分離する | 1 つの呼び出し元によるリソース枯渇を防ぐ |
| フォールバック | 代替手段を提供する | 優雅な機能縮退 |
非同期レジリエンス(Brighter)
メッセージベースの操作と非同期操作向け:
| パターン | 目的 | 使用するタイミング |
|---|---|---|
| リトライ | 失敗したメッセージを再配信する | 一時的な処理障害 |
| デッドレターキュー | 処理できないメッセージを保留する | 有害メッセージ、ビジネスルール違反 |
| サーキットブレーカー | 処理を一時停止する | 下流サービスが利用できない場合 |
| タイムアウト | ハンドラー実行時間に上限を設ける | ハンドラーによる処理のブロックを防ぐ |
クイックスタート:HttpClient での Polly v8
基本設定
// Program.cs or Startup.cs
builder.Services.AddHttpClient<IOrderService, OrderService>()
.AddStandardResilienceHandler();
AddStandardResilienceHandler() は、次の項目を含む事前設定済みのパイプラインを追加します:
- レートリミッター
- リクエスト全体のタイムアウト
- リトライ(指数バックオフ)
- サーキットブレーカー
- 試行ごとのタイムアウト
カスタム設定
builder.Services.AddHttpClient<IOrderService, OrderService>()
.AddResilienceHandler("custom-pipeline", builder =>
{
// Retry with exponential backoff
builder.AddRetry(new HttpRetryStrategyOptions
{
MaxRetryAttempts = 3,
Delay = TimeSpan.FromSeconds(1),
BackoffType = DelayBackoffType.Exponential,
UseJitter = true,
ShouldHandle = new PredicateBuilder<HttpResponseMessage>()
.Handle<HttpRequestException>()
.HandleResult(r => r.StatusCode == HttpStatusCode.ServiceUnavailable)
});
// Circuit breaker
builder.AddCircuitBreaker(new HttpCircuitBreakerStrategyOptions
{
FailureRatio = 0.5,
MinimumThroughput = 10,
SamplingDuration = TimeSpan.FromSeconds(30),
BreakDuration = TimeSpan.FromSeconds(30)
});
// Timeout per attempt
builder.AddTimeout(TimeSpan.FromSeconds(10));
});
Polly パターンの詳細: references/polly-patterns.md を参照してください。
クイックスタート:Brighter メッセージハンドラー
基本的なリトライポリシー
public class OrderCreatedHandler : RequestHandler<OrderCreated>
{
[UsePolicy("retry-policy", step: 1)]
public override OrderCreated Handle(OrderCreated command)
{
// Process order
return base.Handle(command);
}
}
ポリシーレジストリの設定
var policyRegistry = new PolicyRegistry
{
{
"retry-policy",
Policy
.Handle<Exception>()
.WaitAndRetry(
retryCount: 3,
sleepDurationProvider: attempt =>
TimeSpan.FromSeconds(Math.Pow(2, attempt)))
}
};
services.AddBrighter()
.UseExternalBus(/* config */)
.UsePolicyRegistry(policyRegistry);
Brighter パターンの詳細: references/brighter-resilience.md を参照してください。
パターンの選択基準
リトライを使用するタイミング
次の場合はリトライを使用します:
- 障害が一時的なものである可能性が高い(ネットワークの瞬断、一時的な 503)
- 操作が冪等である
- リトライ間の遅延が許容される
次の場合はリトライを使用しないでください:
- 障害がビジネスロジックに起因する(入力検証エラー、400 Bad Request)
- 操作が冪等ではない(冪等性キーを使用する場合を除く)
- 即時の応答が必要である
サーキットブレーカーを使用するタイミング
次の場合はサーキットブレーカーを使用します:
- 停止する可能性のある外部サービスを呼び出す
- 待機せずに速やかに失敗させる必要がある
- 連鎖障害を防ぎたい
- サービスの復旧に時間が必要である
設定のガイダンス: references/circuit-breaker-config.md を参照してください。
DLQ を使用するタイミング
次の場合は DLQ を使用します:
- 最大リトライ回数の後もメッセージを処理できない
- ビジネスルールによって処理が妨げられる
- 手動での介入が必要である
- 障害の監査証跡が必要である
DLQ パターン: references/dlq-patterns.md を参照してください。
リトライ戦略のパターン
即時リトライ
非常に短時間で解消する障害向け:
.AddRetry(new RetryStrategyOptions
{
MaxRetryAttempts = 2,
Delay = TimeSpan.Zero // Immediate retry
});
指数バックオフ
解消までに時間が必要な一時的な障害向け:
.AddRetry(new RetryStrategyOptions
{
MaxRetryAttempts = 4,
Delay = TimeSpan.FromSeconds(1),
BackoffType = DelayBackoffType.Exponential,
UseJitter = true // Prevents thundering herd
});
遅延: 1s → 2s → 4s → 8s(ジッターあり)
線形バックオフ
レート制限のあるサービス向け:
.AddRetry(new RetryStrategyOptions
{
MaxRetryAttempts = 3,
Delay = TimeSpan.FromSeconds(2),
BackoffType = DelayBackoffType.Linear
});
遅延: 2s → 4s → 6s
リトライ戦略の詳細: references/retry-strategies.md を参照してください。
サーキットブレーカーの設定
保守的(高感度なサービス)
.AddCircuitBreaker(new CircuitBreakerStrategyOptions
{
FailureRatio = 0.25, // Open after 25% failures
MinimumThroughput = 5, // Need at least 5 calls to evaluate
SamplingDuration = TimeSpan.FromSeconds(10),
BreakDuration = TimeSpan.FromSeconds(60) // Stay open 60s
});
アグレッシブ(高可用性)
.AddCircuitBreaker(new CircuitBreakerStrategyOptions
{
FailureRatio = 0.5, // Open after 50% failures
MinimumThroughput = 20, // Need 20 calls before evaluation
SamplingDuration = TimeSpan.FromSeconds(30),
BreakDuration = TimeSpan.FromSeconds(15) // Quick recovery attempt
});
詳細な設定: references/circuit-breaker-config.md を参照してください。
デッドレターキューパターン
メッセージ処理に失敗した場合
1. Message received
2. Handler attempts processing
3. Failure occurs
4. Retry policy applied (1...N attempts)
5. All retries exhausted
6. Message moved to DLQ
7. Alert/monitoring triggered
8. Manual investigation
Brighter の DLQ 設定
services.AddBrighter()
.UseExternalBus(config =>
{
config.Publication.RequeueDelayInMs = 500;
config.Publication.RequeueCount = 3;
// After 3 requeues, message goes to DLQ
});
DLQ パターンの全容: references/dlq-patterns.md を参照してください。
複合パターン
あらゆる耐障害性を備えた HTTP クライアント
builder.Services.AddHttpClient<IPaymentGateway, PaymentGateway>()
.AddResilienceHandler("payment-gateway", builder =>
{
// Order matters: outer to inner
// 1. Total timeout (outer boundary)
builder.AddTimeout(TimeSpan.FromSeconds(30));
// 2. Retry (with circuit breaker inside)
builder.AddRetry(new HttpRetryStrategyOptions
{
MaxRetryAttempts = 3,
Delay = TimeSpan.FromMilliseconds(500),
BackoffType = DelayBackoffType.Exponential,
UseJitter = true
});
// 3. Circuit breaker
builder.AddCircuitBreaker(new HttpCircuitBreakerStrategyOptions
{
FailureRatio = 0.5,
MinimumThroughput = 10,
BreakDuration = TimeSpan.FromSeconds(30)
});
// 4. Per-attempt timeout (inner)
builder.AddTimeout(TimeSpan.FromSeconds(5));
});
フォールバックを備えたメッセージハンドラー
public class ProcessPaymentHandler : RequestHandler<ProcessPayment>
{
[UsePolicy("circuit-breaker", step: 1)]
[UsePolicy("retry", step: 2)]
[UsePolicy("fallback", step: 3)]
public override ProcessPayment Handle(ProcessPayment command)
{
_paymentService.Process(command);
return base.Handle(command);
}
}
可観測性
Polly テレメトリ
services.AddResiliencePipeline("my-pipeline", builder =>
{
builder.AddRetry(/* options */)
.ConfigureTelemetry(LoggerFactory.Create(b => b.AddConsole()));
});
監視する主なメトリクス
| メトリクス | 目的 | アラートのしきい値 |
|---|---|---|
| リトライ回数 | 一時的な障害を追跡します | 1 分あたり > 3 |
| サーキットの状態 | サービスの健全性を追跡します | 状態 = Open |
| DLQ の深さ | 処理の失敗を追跡します | > 0 |
| タイムアウト率 | 応答の遅いサービスを追跡します | > 5% |
アンチパターン
過剰なリトライ
問題: リトライの回数が多すぎたり、間隔が短すぎたりします。
// BAD: 10 immediate retries
.AddRetry(new RetryStrategyOptions { MaxRetryAttempts = 10 });
対処法: 指数バックオフを使用し、リトライ回数を制限します。
// GOOD: 3 retries with backoff
.AddRetry(new RetryStrategyOptions
{
MaxRetryAttempts = 3,
Delay = TimeSpan.FromSeconds(1),
BackoffType = DelayBackoffType.Exponential
});
一時的ではない障害のリトライ
問題: ビジネスロジックの障害をリトライします。
// BAD: Retrying 400 Bad Request
ShouldHandle = new PredicateBuilder<HttpResponseMessage>()
.HandleResult(r => !r.IsSuccessStatusCode)
対処法: 一時的な障害のみをリトライします。
// GOOD: Only retry transient HTTP codes
ShouldHandle = new PredicateBuilder<HttpResponseMessage>()
.Handle<HttpRequestException>()
.HandleResult(r => r.StatusCode is
HttpStatusCode.ServiceUnavailable or
HttpStatusCode.GatewayTimeout or
HttpStatusCode.RequestTimeout)
サーキットブレーカーの欠如
問題: サービス停止中も延々とリトライします。
対処法: 外部呼び出しでは、必ずリトライとサーキットブレーカーを組み合わせます。
ブラックホール化した DLQ
問題: メッセージが DLQ に送られ、二度と処理されません。
対処法:
- DLQ の深さを監視します
- アラートを設定します
- 再処理の仕組みを実装します
- 調査手順を文書化します
参考資料
references/polly-patterns.md- Polly v8 の包括的なパターンreferences/circuit-breaker-config.md- サーキットブレーカーの設定ガイドreferences/retry-strategies.md- リトライ戦略のパターンreferences/brighter-resilience.md- Brighter のメッセージハンドラーにおける耐障害性references/dlq-patterns.md- デッドレターキューのパターン
関連スキル
fitness-functions- パフォーマンス適合性関数で耐障害性をテストしますmodular-architecture- モジュールごとに耐障害性の関心事を分離しますadr-management- 耐障害性に関する決定を文書化します
最終更新日: 2025-12-22
ユーザー向けインターフェース
ユーザーがこのスキルを直接呼び出すと、コードベースの耐障害性パターンを監査します。
実行ワークフロー
- 引数の解析 - 対象範囲(既定値は現在のディレクトリ)、
--detailedフラグ、出力ディレクトリを抽出します。 - 耐障害性アナライザーエージェントの起動 - HTTP クライアント、メッセージハンドラー、データベース呼び出し、外部サービス接続を分析し、耐障害性パターン(リトライ、サーキットブレーカー、タイムアウト、DLQ)を確認します。
- ギャップの特定 - 見つかった依存関係と、耐障害性ハンドラーが設定された依存関係を比較します。アンチパターン(例外のキャッチと握りつぶし、タイムアウトの欠如)を検出します。
- 監査レポートの生成 - エグゼクティブサマリー、コードの場所と推奨事項を含む重大なギャップ、既存の優れた実践、検出されたアンチパターン、優先順位付きの改善計画を含むレポートを作成します。
- 詳細な出力(
--detailedが指定されている場合)- コードスニペット、変更前後の例、設定テンプレート、テストのガイダンスを含めます。 - 結果の保存 -
docs/audits/resilience-audit-[date].md(またはカスタムの--dir)に保存します。
バージョン履歴
- v1.0.0(2025-12-26):初回リリース