UnsplashのNenad Grujicが撮影した写真
マイクロサービスアーキテクチャでは、サービス間の呼び出しが連鎖するため、1つの障害が別のサービスへ波及しやすいという課題があります。そこで重要になるのが、障害の影響を局所化し、無駄なリトライや待ち時間を減らすための「サーキットブレーカー」パターンです。この記事では、サーキットブレーカーの基本概念から実装時の判断ポイント、運用で効くベストプラクティスまでを整理します。
サーキットブレーカーは、分散システムにおける代表的なレジリエンス設計パターンの一つです。一定の条件で外部呼び出しを「速やかに失敗させる」ことで、障害の拡大やリソース枯渇を防ぎ、システム全体の安定性を保つことを目的とします。
とくに、下記のような状況で効果を発揮します。
サーキットブレーカーの動作は、一般的に次の3状態で説明されます。
この仕組みにより、「障害中は無駄に叩かない」「回復したら段階的に戻す」という制御が可能になります。
状態遷移のイメージは次のとおりです。
| 現在の状態 | 遷移のきっかけ | 次の状態 |
|---|---|---|
| Closed | 失敗率やタイムアウトがしきい値を超えた | Open |
| Open | 一定時間(待機時間)が経過した | Half-Open |
| Half-Open | 試行リクエストが一定条件で成功した | Closed |
| Half-Open | 試行リクエストが失敗した | Open |
Half-Openで「何回試すか」「何回失敗したらOpenに戻すか」は実装・ライブラリで調整できるため、システムの特性(ピーク時の負荷、復旧の揺らぎ)に合わせて設計します。
サーキットブレーカーはフェイルファストの考え方を実装レベルで具体化したものと捉えられます。障害が疑われる呼び出しを「待つ」のではなく「早く諦める」ことで、上流のスレッド、キュー、コネクションなどの共有リソースを守るという意味で、分散システムの安定運用に直結します。
ただしフェイルファストは万能ではありません。たとえば一時的なネットワーク揺らぎを「障害」と誤判定すると、必要以上にOpenになりユーザー影響が拡大します。そこで次章以降の「しきい値設計」「観測」「テスト」が重要になります。
マイクロサービスアーキテクチャは、機能を小さなサービスに分割し、サービス同士がAPI等で連携しながらシステムを構成する設計手法です。サービス単位で開発・デプロイ・スケールできる一方、サービス間の呼び出しが増えることで「分散システム特有の失敗」が表面化しやすくなります。
分散システムでは、下流の遅延やエラーが上流へ波及しやすく、カスケード障害(連鎖障害)につながることがあります。典型例は次の流れです。
このような状況では、「呼び出しを続けること」自体が障害を長引かせる要因になり得ます。
サーキットブレーカーは、サービス間呼び出しの失敗傾向を検知し、問題が疑われる経路を一時的に遮断します。これにより、障害を「局所」に閉じ込め、正常系の処理や別経路の処理を守ります。
重要なのは、遮断中に「ユーザー体験をどう落とすか」です。フォールバックや簡易表示、キャッシュ応答、後で再試行する非同期化など、ビジネス要件に合わせた設計が必要になります。
サーキットブレーカーは、障害時に無駄な待機と負荷を減らすだけでなく、復旧時の「押し寄せ」を抑える効果も期待できます。Half-Openの段階的試行により、回復途中の下流へ大量トラフィックを流し込むことを避け、自動的かつ段階的な復旧を実現しやすくなります。
実装の核は「失敗傾向の測定」と「状態遷移」です。一般的には、次のような要素を組み合わせます。
ここでのポイントは、「失敗の定義」と「計測の窓」を曖昧にしないことです。たとえば「下流のバリデーションエラー」まで失敗に含めると、障害ではないのにOpenになり得ます。逆に、タイムアウトを失敗に含めないと、待機で上流リソースが枯渇します。
設定パラメータは、サーキットブレーカーの性格を決めます。
また、サーキットブレーカーは単体で完結しません。タイムアウトとリトライを併用する場合は、リトライ回数・間隔(指数バックオフ等)と整合するように設計することが重要です。無計画なリトライは、障害を悪化させやすい代表例です。
Open時に重要になるのがフォールバックです。代表例は次のとおりです。
フォールバックは「動けばよい」ではなく、データ整合性とユーザー説明がセットです。たとえばキャッシュ応答なら「いつ時点の情報か」、簡易応答なら「一時的に一部情報が表示できない」など、UI・API仕様としての明確化が求められます。
運用では、少なくとも次の指標を観測できるようにします。
可視化の目的は「障害検知」だけではありません。設定が厳しすぎてOpenが頻発していないか、フォールバックが常態化していないかを把握し、継続的にチューニングするための基盤になります。
サーキットブレーカーは、正常系だけでは品質が確認できません。次の観点でテストを組み合わせます。
ここまでの設計・観測・テストが揃ってはじめて、サーキットブレーカーは「障害時に役立つ仕組み」として機能します。
すべての呼び出しに付けると複雑性と運用負荷が増えます。一般には次のような観点で適用箇所を選びます。
フォールバックは「障害時の代替」だけでなく「負荷時の保険」にもなります。ただし、フォールバック自体が重い処理(別サービスへの多段呼び出し等)になっていると、障害時に別のボトルネックを作ります。フォールバックは軽量で、依存関係を増やさないことが基本です。
チューニングの中心は「誤検知」と「検知遅延」のバランスです。代表的な調整ポイントは次のとおりです。
また、チューニングは一度で終わりません。監視データ(エラー率、レイテンシ、Open頻度)と、実際のユーザー影響(エラー画面、待ち時間)を突き合わせて継続的に調整します。
サーキットブレーカーは、他のレジリエンス手法と組み合わせることで効果が上がります。
一方で、避けたい運用もあります。
サーキットブレーカーは、分散システムにおいて障害の波及を抑え、無駄な待機やリトライでリソースが枯渇する事態を防ぐための重要な設計パターンです。状態遷移(Closed / Open / Half-Open)としきい値設計により、障害時は速やかに遮断し、復旧時は段階的に戻すことができます。
一方で、効果を最大化するには、失敗の定義、タイムアウト、フォールバック、監視、そして障害を想定したテストまでを含めた設計が欠かせません。自社のSLOや運用体制に合わせてパラメータを調整し、継続的に改善することで、回復性と可用性の高いマイクロサービス基盤を実現できます。
下流サービスの障害や遅延が広がるのを防ぎ、無駄な待機やリトライによるリソース枯渇を避けるために使います。
Closedは通常どおり呼び出す状態で、Openは下流へ送らずに即座に失敗させる状態です。
復旧したかどうかを確認するために少数のリクエストだけを通し、結果に応じてClosedかOpenに戻します。
平常時のエラー率とレイテンシの実測データを基に、誤検知と検知遅延のバランスが取れる値にします。
一時的な遅延を障害と誤判定しやすくなり、Openが頻発して可用性が下がることがあります。
用意できるなら望ましいですが、データ整合性や仕様説明を含めて設計できない場合は安易に導入しない方が安全です。
無計画なリトライは負荷を増やすため、回数制限と指数バックオフなどで慎重に制御します。
重要度や外部依存性が高い経路を優先し、効果と運用負荷のバランスを見て適用範囲を決めます。
状態遷移、失敗率、タイムアウト率、レイテンシの分位点、フォールバック発生回数を継続的に観測します。
遅延やエラーを意図的に起こし、OpenとHalf-Openの挙動、フォールバックの品質、負荷時の安定性を確認します。