サーキットブレーカーとは?マイクロサービスの障害連鎖を止める仕組みと実装・導入判断を解説

サーキットブレーカーは、マイクロサービスで一つのサービスの遅延・停止が呼び出し元へ次々と伝播する「カスケード障害」を、途中で回路を遮断して食い止めるレジリエンスパターンです。株価急落時に取引を止める金融の制度や、配線を守る電気の遮断器と同じ名前ですが、本記事が扱うのは分散システムのソフトウェア実装です。Closed・Open・Half-Openという3つの状態でどう障害を検知し遮断するか、Resilience4jとIstio/Envoyという2層の実装差、リトライやタイムアウトとの組み合わせ方、そして採用すべき要件と過剰投資になる場面までを実装視点で整理します。

目次

まとめ:サーキットブレーカー導入の要点と全体障害を防ぐ判断

結論から示します。サーキットブレーカーは「落ちている依存先を呼び続けてスレッドを枯渇させ、自分まで巻き添えで倒れる」事故を防ぐための仕組みです。呼び出しの失敗率が設定したしきい値を超えたら回路をOpenにして即座に失敗を返し、一定時間後にHalf-Openで少数の試験呼び出しを通して回復を確かめます。

実装は大きく2層に分かれます。アプリのコード内に組み込むライブラリ型(JavaならResilience4j 2.x系)と、サービスメッシュのプロキシ側で効かせるインフラ型(Envoy/Istio 1.x系)です。両者は排他ではなく、担当する障害の粒度が違います。

採用判断の軸は一つです。ネットワーク越しに別プロセスを同期呼び出しし、その障害が連鎖して全体を止めうるか。単一プロセス内のメソッド呼び出しや、非同期のメッセージング主体の構成では、サーキットブレーカーはむしろ複雑さを持ち込みます。分散呼び出しの本数と障害の伝播経路を先に描き、守るべき境界にだけ入れるのが要点です。

サーキットブレーカーの定義とマイクロサービスで障害が連鎖する仕組み

マイクロサービスは1リクエストの裏で複数サービスを同期的に呼び合います。この構造が、サーキットブレーカーを必要にします。

カスケード障害が発生する経路とスレッド枯渇に至る具体的な故障の流れ

注文サービスが在庫サービスをHTTPで同期呼び出しする構成を考えます。在庫サービスが応答を返さなくなると、注文サービスのスレッドは応答を待ったまま塞がれた状態です。リクエストが秒間数百件あれば、待機スレッドはすぐにプールの上限に達します。

ここで起きるのが巻き添えです。塞がれた注文サービスは、在庫と無関係な「注文履歴表示」まで処理できなくなります。1つの依存先の遅延が、それを呼ぶサービス全体を機能停止させ、さらにその呼び出し元へ伝播する。この連鎖がカスケード障害で、Michael Nygardが『Release It!』(2007)で警告した典型的な分散システムの故障です。

フェイルファストの原則と回路を遮断することが全体復旧を早める理由

サーキットブレーカーの発想は「速く失敗する(フェイルファスト)」です。依存先が落ちていると分かっているなら、タイムアウトまで待たずに即座にエラーを返し、呼び出し元のスレッドを解放します。

効果は2つあります。一つは、呼び出し元のリソース枯渇を防ぎ、無関係な機能を生かすこと。もう一つは、落ちた依存先に殺到する再送を止め、復旧しようとするサービスへ回復の余地を残すことです。落ちた側を叩き続けない配慮が、全体の復旧を早めます。マイクロサービスの前提となる分散構成そのものについては、モノリスとマイクロサービス・モノリシックの違いを先に押さえると、なぜ同期呼び出しの境界が増えるのかが理解しやすくなります。

Closed・Open・Half-Openの3状態と回路を開くしきい値の決め方

サーキットブレーカーは有限状態機械です。3つの基本状態を、設定したしきい値で行き来します。

Closed・Open・Half-Openの3状態と遷移が起こる具体的な条件

各状態の振る舞いは明確に分かれます。

状態 呼び出しの扱い 次の状態への遷移条件
Closed(閉) 通常どおり依存先へ通す。失敗率を記録 失敗率がしきい値超過 → Open
Open(開) 依存先を呼ばず即座に失敗を返す 待機時間が経過 → Half-Open
Half-Open(半開) 限られた試験呼び出しだけ通す 試験成功 → Closed/試験失敗 → Open

回路が閉じている(Closed)ときは電気が流れる、開く(Open)と流れない、という電気回路の比喩がそのまま名前の由来です。Half-Openは「回復したか少しだけ様子見する」偵察の状態だと捉えると分かりやすいはずです。

失敗率・スライディングウィンドウ・待機時間という主要パラメータの設定基準

Resilience4jのCircuitBreakerを例にすると、判断を左右する主なパラメータは次の3つです。

  • failureRateThreshold:Openへ移る失敗率のしきい値(既定50%系)。低くしすぎると正常な一時ゆらぎで開き、高すぎると障害を見逃す
  • slidingWindowSize:失敗率を集計する直近の呼び出し数または時間幅。小さいと過敏に、大きいと反応が鈍る
  • waitDurationInOpenState:Openを保つ時間。依存先の復旧見込み時間に合わせる

加えてResilience4jには、基本3状態のほかにMETRICS_ONLY・DISABLED・FORCED_OPENという特殊状態があり、計測だけ行う・無効化する・強制的に開く、といった運用制御ができます(2.x系・2026年時点)。しきい値は「正常時の失敗率の実測値」を先に取り、その上に余裕を乗せて決めるのが実務の順序です。数字を勘で置くと、開かない/開きっぱなしのどちらかに倒れます。

Resilience4jとIstio/Envoyで異なる2層のサーキットブレーカー実装

サーキットブレーカーは実装する層で性格が変わります。ライブラリ型とインフラ型を分けて捉えます。

ライブラリ型(Resilience4j)とHystrixからの移行という現在地

Javaで主流の実装がResilience4jです。アノテーションや設定でメソッド単位に回路を巻け、フォールバック処理も宣言的に書けます。かつて広く使われたNetflix Hystrixは、Netflixが2018年にメンテナンスモードへ移し新機能開発を止めました。Spring Cloud CircuitBreakerもHystrix直結をやめ、標準の実装先としてResilience4jを案内しています。新規のSpring Boot構成でHystrixを選ぶ理由は、2026年時点ではほぼありません。

ライブラリ型の強みは、呼び出し単位の細かい制御とアプリのビジネスロジックに沿ったフォールバックです。弱みは、言語ランタイムに縛られる点にあります。JavaのResilience4jはJVM系サービスにしか効きません。

インフラ型(Envoy/Istio)が担うプロキシ層の回路遮断と外れ値検知

サービスメッシュを敷いている場合、Envoyプロキシ側でもサーキットブレーカーが効きます。IstioならDestinationRuleで、コネクション数・保留リクエスト数・並列リクエスト数の上限を定め、上限超過の呼び出しを弾きます。加えて外れ値検知(outlier detection)で、連続エラーを返すホストを負荷分散の対象から一時的に外します(Istio 1.x系)。プロキシ層でこうした遮断や通信制御をまとめて担う基盤がサービスメッシュの仕組みと導入判断で、東西トラフィック全体を横断的に守る発想です。

インフラ型の利点は、言語を問わず全サービスへ横断的に効くことです。コードに手を入れずポリシーで一律に守れます。一方、アプリ固有の「この呼び出しが失敗したらキャッシュ値を返す」といったビジネス寄りのフォールバックは書けません。プロキシ層で境界を守るという発想は、APIゲートウェイの役割とサービスメッシュとの違いと併せて見ると、どこで遮断を効かせるべきかの全体像がつかめます。実務ではメッシュで粗く全体を守り、要所のコード内でライブラリ型を重ねる二段構えが現実的です。

リトライ・タイムアウト・フォールバックと組み合わせるレジリエンス設計

サーキットブレーカーは単独では機能しません。他のレジリエンスパターンと順序立てて組み合わせて初めて効きます。

タイムアウトとリトライの併用で陥りやすいリトライストームという失敗パターン

まず必須なのがタイムアウトです。同期呼び出しに上限時間がなければ、そもそもスレッドが解放されず、サーキットブレーカー以前の問題になります。次にリトライですが、ここに落とし穴があります。

依存先が高負荷で落ちかけているとき、全クライアントが一斉に再送すると負荷がさらに増え、復旧を妨げます。これがリトライストームです。回避には、再送間隔を指数関数的に延ばすエクスポネンシャルバックオフと、間隔にゆらぎを与えるジッターを併用します。そしてリトライの外側にサーキットブレーカーを置き、一定回数失敗したら再送そのものを止める。この順序が守りの肝です。

フォールバックの設計とバルクヘッドで依存先ごとに障害を隔てる方法

回路が開いたとき、ユーザーへ何を返すかがフォールバックです。返せるものは障害の性質で変わります。

  • キャッシュ済みの直近値を返す(商品一覧など、多少古くても許容できる読み取り)
  • 機能を縮退させた既定値を返す(レコメンドが出せないなら人気順で代替)
  • 明示的なエラーと再試行の案内を返す(決済など、古い値を返してはいけない処理)

決済のように整合性が絶対の処理で古いキャッシュを返すのは事故です。フォールバックは業務の許容度で決めます。さらにバルクヘッド(隔壁)で依存先ごとにスレッドプールを分けておくと、一つの依存先の詰まりが他へ波及しません。船の防水区画と同じ発想で、障害を区画内に閉じ込めます。

サーキットブレーカーを採用すべき要件と過剰投資になる構成の見極め

ここは判断を言い切ります。サーキットブレーカーは万能の保険ではなく、効く条件がはっきりしたパターンです。

サーキットブレーカーの導入効果が大きくなる構成の具体的な条件

次の条件が重なるほど、導入効果は大きくなります。

  • ネットワーク越しの同期呼び出しが多段に連なる(サービスAがBを、BがCを呼ぶ)
  • 依存先に外部API・決済・在庫など「落ちうる」要素が含まれる
  • トラフィックが高く、待機スレッド枯渇が現実的なリスクになる

この構成では、1本の依存先の劣化が全体を止めます。守るべき境界を1〜2個に絞り、そこに集中して入れるのが費用対効果の高い順序です。全呼び出しに一律で巻くのは、設定の管理コストが跳ね上がるだけで割に合いません。

サーキットブレーカーの導入を見送るべき場面と過剰設計に陥る失敗パターン

逆に、次の場合はサーキットブレーカーを入れない、または後回しにすべきです。

第一に、モノリスや単一プロセス内のメソッド呼び出しが主体の構成です。ネットワーク障害の連鎖が起きないため、回路を巻いても守る対象がありません。第二に、通信の大半が非同期メッセージング(キュー経由)で、呼び出し元が応答を待たない構成です。待機によるスレッド枯渇が起きにくく、メッセージの再処理やデッドレターキューで守るほうが素直に運びます。第三に、サービスが2〜3個の小規模構成で、まだ障害の伝播経路が単純な段階です。ここでサービスメッシュとサーキットブレーカーを先回りで全面導入すると、運用する分散トレーシングやしきい値調整の負担が、防げる障害の頻度を上回ります。

マイクロサービス化そのものを検討している段階なら、遮断の仕組みを足す前に境界の切り方を決めるのが先です。Webシステム開発では、既存システムのモダナイズや分散構成の設計を、こうした障害設計まで含めて相談いただけます。パターンを入れること自体が目的化すると、守るべき障害より運用コストが勝ちます。

サーキットブレーカーの実装・設定と導入判断に関するよくある質問

実装や導入判断でよく挙がる質問をまとめます。金融・電気のサーキットブレーカーではなく、マイクロサービスのパターンとしての回答です。

サーキットブレーカーとリトライはどちらを先に実装すべきですか?

タイムアウト、リトライ、サーキットブレーカーの順で考えるのが基本です。まず全同期呼び出しにタイムアウトを設定し、次にバックオフとジッター付きのリトライを足し、その外側にサーキットブレーカーを置きます。リトライの内側に回路を置くと、回路が開いているのに再送が走る矛盾が起きます。順序を守ることが安定動作の前提です。

Resilience4jとHystrixはどちらを選べばよいですか?

新規開発ではResilience4j 2.x系を選びます。Netflix Hystrixは2018年にメンテナンスモードへ入り新機能開発が止まっており、Spring Cloud CircuitBreakerもResilience4jを標準の実装先として案内しています。既存のHystrix資産が大規模に動いている場合を除き、2026年時点で新規にHystrixを採用する理由はほぼありません。

サービスメッシュを入れればライブラリのサーキットブレーカーは不要ですか?

不要にはなりません。Istio/Envoyのインフラ型は言語非依存で全体を粗く守れますが、コネクション/リクエスト上限と外れ値検知が中心で、アプリ固有のフォールバック(キャッシュ値を返す等)は書けません。粗い防御をメッシュで、業務に沿った細かい遮断とフォールバックをコード内で、という二段構えが実務的です。

AWS環境でサーキットブレーカーはどう実装しますか?

アプリ層はResilience4jなどのライブラリで実装するのが基本で、これはAWSでもオンプレでも変わりません。加えてApp Meshやロードバランサ側で外れ値検知に近い挙動を設定できます。マネージドサービス(SQS等の非同期)主体の構成なら、同期呼び出し自体が減るため、キューの再処理やデッドレターキューで代替できる範囲も広がります。

しきい値は最初にどんな値を設定すればよいですか?

いきなり理想値は置けません。まず正常稼働時の失敗率とレイテンシを実測し、その分布の上に余裕を乗せてfailureRateThresholdを決めます。集計窓(slidingWindowSize)は数十呼び出し程度から始め、過敏なら広げる調整で構いません。Open保持時間は依存先の復旧見込みに合わせます。運用しながら実測値で調整する前提で、初期値は「開かなすぎない」側に寄せるのが安全です。

関連記事

資料請求

RELATED POSTS 関連記事