サーキットブレーカーパターン

英語名 Circuit Breaker Pattern
読み方 サーキット ブレーカー パターン
難易度
所要時間 実装に1〜3日
提唱者 マイケル・ナイガード(『Release It!』著者)
目次

ひとことで言うと
#

電気のブレーカーと同じ発想で、呼び出し先サービスの障害を検知したら自動的に通信を遮断し、障害が連鎖(カスケード)するのを防ぐパターン。一定時間後に再接続を試みて回復を確認する。

押さえておきたい用語
#

押さえておきたい用語
Closed(閉)
サーキットブレーカーの通常状態。リクエストはそのまま通過し、失敗率を記録する。
Open(開)
障害を検知した状態。リクエストを即座に失敗させ、呼び出し先への通信を遮断する。フォールバック応答を返す。
Half-Open(半開)
回復確認のために少量のリクエストだけ通す状態。成功すればClosedに戻り、失敗すれば再びOpenになる。
フォールバック
ブレーカーOpen時にユーザーに返す代替の応答。キャッシュ応答やデフォルト値など。
カスケード障害
1つのサービスの障害が連鎖的に他のサービスに波及し、システム全体が停止する現象。サーキットブレーカーが防ぐ対象。

サーキットブレーカーパターンの全体像
#

Closed→Open→Half-Openの3状態遷移で障害の連鎖を防ぐ
Closed(閉)通常状態リクエストは通過失敗率を監視閾値超え→Openへ障害検知Open(開)障害遮断状態リクエストを即失敗フォールバック応答タイマー後→Half-OpenタイマーHalf-Open(半開)回復確認状態少量のリクエストを通す成功→Closedへ復帰失敗→Openに戻る成功 → Closedに復帰失敗→Open3状態の自動遷移で障害を検知・遮断・回復する
サーキットブレーカーの導入フロー
1
状態理解
Closed/Open/Half-Openの遷移
2
閾値設定
失敗率とタイムアウトを定義
3
フォールバック
Open時の代替応答を実装
4
モニタリング
状態遷移を可視化・アラート

こんな悩みに効く
#

  • 1つの外部サービスの障害で、自分のシステム全体が巻き込まれて落ちてしまう
  • タイムアウト待ちのリクエストが溜まり、スレッドプールが枯渇する
  • 障害時にユーザーを長時間待たせてしまう

基本の使い方
#

ステップ1: サーキットブレーカーの3つの状態を理解する

サーキットブレーカーには3つの状態がある。

  • Closed(閉): 通常状態。リクエストはそのまま通過する
  • Open(開): 障害検知状態。リクエストを即座に失敗させる(フォールバック応答を返す)
  • Half-Open(半開): 回復確認状態。少量のリクエストだけ通し、成功すればClosedに戻る

ポイント: この3状態の遷移が、サーキットブレーカーの核心。

ステップ2: 閾値とタイムアウトを設定する

いつブレーカーを開くかのパラメータを決める。

  • 失敗回数の閾値(例: 直近10回中5回失敗したらOpen)
  • タイムアウト時間(例: 3秒以内に応答がなければ失敗とみなす)
  • Open状態の維持時間(例: 30秒後にHalf-Openへ遷移)

ポイント: 閾値は厳しすぎても緩すぎてもダメ。本番の挙動を見ながらチューニングする。

ステップ3: フォールバック処理を実装する

ブレーカーがOpenの時に代替の応答を返す仕組みを作る。

  • キャッシュされた前回の正常応答を返す
  • デフォルト値や簡略化されたレスポンスを返す
  • 「現在サービスが混み合っています」のようなユーザー向けメッセージを返す

ポイント: Open時に単にエラーを返すだけでは不十分。ユーザー体験を考えたフォールバックを設計する。

ステップ4: モニタリングとアラートを設定する

サーキットブレーカーの状態遷移を可視化する。

  • Open/Closed/Half-Openの状態変化をメトリクスとして記録する
  • Open状態への遷移をアラートで通知する
  • ダッシュボードで全サービスのブレーカー状態を一覧できるようにする

ポイント: ブレーカーが開いたことに気づけなければ、根本原因の対処が遅れる。

具体例
#

例1:ECサイトの決済API障害で注文処理全体の停止を防ぐ

状況: ECサイトの注文処理が外部決済APIを呼び出している。決済APIが不安定になると注文処理全体がタイムアウトで詰まる。

Closed状態: 決済APIへのリクエストは通常通り送信。レスポンスタイムと成功率を記録。

障害発生: 決済APIが応答しなくなる。直近20リクエスト中15回がタイムアウト → 閾値(75%)超え → Open状態に遷移

Open状態: 決済APIへのリクエストを即座にブロック。「決済処理を一時的に受け付けられません。しばらくしてから再度お試しください」とユーザーに返す。スレッドプールの枯渇を防止。

30秒後 → Half-Open: 1リクエストだけ決済APIに送信。成功 → Closed状態に復帰。失敗 → 再びOpenで30秒待つ。

結果: 決済APIの障害中も商品閲覧・カート操作は正常に動作し続けた。スレッドプール枯渇によるシステム全体の停止を回避した。

例2:マイクロサービス間の通信にサーキットブレーカーを導入し、カスケード障害を根絶する

状況: 注文→在庫→出荷→通知の4サービスが連鎖呼び出し。通知サービスのDB障害で通知が遅延 → 出荷サービスのスレッドが枯渇 → 在庫サービスも停止 → 注文不能に。年に3回このカスケード障害が発生。

サーキットブレーカー導入:

  • 各サービス間の呼び出しにResilience4jのCircuit Breakerを適用
  • 失敗率50%超でOpen、30秒後にHalf-Open
  • 通知サービス: フォールバックは非同期キューに投入(後で再送)
  • 在庫サービス: フォールバックはキャッシュされた在庫数を返す(10秒前のデータ)

結果: 通知サービスが障害を起こしても、注文・在庫・出荷は正常動作を維持。カスケード障害の発生が年3回→ゼロになり、年間のダウンタイムが4.5時間→15分に短縮した。

例3:外部天気APIへのサーキットブレーカーで、旅行サイトのレスポンスタイムを安定化する

状況: 旅行予約サイトが外部天気APIを呼び出して旅行先の天気情報を表示。天気APIが月に2〜3回スローダウン(レスポンス8秒)し、その間ページ全体の表示が遅延。

設計:

  • タイムアウト: 2秒
  • 閾値: 直近10リクエスト中4回タイムアウトでOpen
  • Open維持時間: 60秒
  • フォールバック: 「天気情報を取得中です」のプレースホルダーを表示し、クライアントサイドで非同期リロード

結果: 天気APIのスローダウン時、サーキットブレーカーが2秒以内にOpenに遷移。ページ全体のレスポンスタイムが8秒→1.2秒に改善(天気なしでの表示)。ユーザーのページ離脱率が天気API障害時に38%→12%に低下した。

やりがちな失敗パターン
#

  1. 閾値を固定値のまま放置する — トラフィックが増えると正常時でも閾値に達してしまう。失敗率(パーセンテージ)ベースの閾値を使うこと
  2. フォールバックを設計しない — Open時にただエラーを返すだけだと、ブレーカーの意味が半減する。ユーザー体験を維持するフォールバックを必ず用意する
  3. Half-Open時のリクエスト数が多すぎる — 回復確認で大量リクエストを送ると、回復しかけたサービスを再び潰す。最小限のリクエストで回復を確認する
  4. ブレーカーの状態変化をモニタリングしない — Openに遷移したことに誰も気づかず、フォールバック状態が長時間続く。状態遷移をアラートで即時通知する仕組みが必須

まとめ
#

サーキットブレーカーは分散システムにおける 「安全装置」。障害を検知して自動的に通信を遮断し、システム全体の連鎖的な障害を防ぐ。Closed → Open → Half-Open の3状態遷移を正しく設計し、フォールバックとモニタリングを組み合わせることで、レジリエントなシステムを実現しよう