サーキットブレーカーパターンとは何か
サーキットブレーカーパターンとは、あるサービスが別のサービスを呼び出す際、呼び出し先で障害が続いている場合に、それ以上の呼び出しを一時的に自動で遮断する設計手法です。名前の通り、家庭用の電気のブレーカーと同じ発想に基づいています。
「家庭のブレーカー」に例えると
家庭の分電盤にあるブレーカーは、電気の使いすぎや漏電などの異常を検知すると、被害が広がる前に自動で電気を遮断してくれます。もしブレーカーがなければ、異常な電流が流れ続け、配線の発熱や火災といった、より深刻な被害につながりかねません。
ソフトウェアの世界でも同じことが起こります。あるサービスが不調になっているのに、他のサービスがそれを知らずに呼び出し続けると、待ち時間の増加やリソースの枯渇が連鎖的に広がり、最終的にシステム全体が巻き込まれてしまうことがあります。サーキットブレーカーパターンは、この「障害の連鎖」を、電気のブレーカーと同じように未然に防ぐ役割を果たします。
図で見る、3つの状態
サーキットブレーカーは、主に3つの状態を行き来しながら動作します。Microsoft Azure Architecture Centerの公式解説でも、この仕組みが説明されています。
- Closed(閉じている):通常の状態です。呼び出しはそのまま相手に届けられます
- Open(開いている):一定回数以上の失敗が続くと、この状態に切り替わります。呼び出し自体を試みることなく、即座にエラーを返します
- Half-Open(半開き):一定時間が経過すると、様子見として一部のリクエストだけを試験的に通します。成功すればClosedに戻り、失敗すれば再びOpenに戻ります
なぜ「即座に失敗させる」ことが重要なのか
一見、リクエストを失敗させるのは望ましくないことのように思えます。しかし、相手のサービスがすでに不調な状態で、律儀に呼び出しを続けてタイムアウトを待つよりも、早い段階で諦めて即座にエラーを返す方が、システム全体にとって健全です。無駄な待ち時間やリソースの消費を防げるだけでなく、不調なサービス側に余計な負荷をかけ続けることも防げます。
実際の開発現場でよくある設計の悩みどころ
- 失敗と判定する基準の設定が難しい:厳しすぎるとちょっとした一時的な遅延でもOpenになってしまい、逆に緩すぎると連鎖障害を防ぎきれません
- Open状態の間、利用者にどう表示するか:エラーをそのまま表示するのではなく、キャッシュされた古いデータを代わりに表示するなど、体験を大きく損なわない工夫が求められることがあります
- 監視・アラートとの連携を忘れがち:サーキットブレーカーがOpenになったこと自体を検知できる仕組みがないと、障害が起きていることに気づくのが遅れてしまいます
似た設計パターンとの違い
以前紹介した冪等性が「同じリクエストを繰り返しても結果が変わらないようにする」考え方であるのに対し、サーキットブレーカーパターンは「相手が不調な時に、そもそも呼び出し自体を控える」という、少し異なる観点の設計手法です。両者は組み合わせて使われることも多く、リトライ処理とあわせて実装されるのが一般的です。
こうして見ると
サーキットブレーカーパターンは、1つのサービスの不調が、システム全体を巻き込む障害に発展するのを防ぐための、重要な設計手法です。特に複数のサービスが連携するシステムを設計・運用する際は、意識しておく価値のある考え方です。
参考
※ 具体的な実装方法は使用しているフレームワークやライブラリによって異なるため、詳しくは各公式ドキュメントもあわせてご確認ください。