Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】Stop Hammering Broken APIs - the Circuit Breaker Pattern

2025年09月18日に「Dev.to」が公開したITニュース「Stop Hammering Broken APIs - the Circuit Breaker Pattern」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

サービス連携システムで、一つが不調だと全体が不安定になる。サーキットブレーカーパターンは、頻繁に失敗するサービスへのリクエストを一時的に遮断し、無駄なリソース消費を避け、サービス回復を促し、システム安定性を保つ。

ITニュース解説

現代のアプリケーションは、もはや単独で動作することは少なく、決済サービス、おすすめ機能、位置情報プロバイダーなど、多くの外部サービスと連携しているのが一般的である。このような外部サービスへの依存関係によって、アプリケーションは強力で多機能になる一方で、一部のサービスが応答速度を落としたり、完全に停止したりすると、システム全体が不安定になるという脆さも抱えている。

もし、これらの連携しているサービスの一つが応答速度を落としたり、完全に停止したりし始めたらどうなるだろうか。何も対策がなければ、あなたのアプリケーションはその失敗しているサービスに対して何度もリクエストを送り続け、それらのリクエストがキューに積み重なったり、タイムアウトを待つ時間が長くなったりするだろう。その結果、貴重なシステムリソースが無駄になり、ユーザーは待たされ続けることで不満を募らせるだけでなく、一つのサービスの障害が次々と他のサービスにも波及し、最終的にシステム全体が停止してしまう「カスケード障害」と呼ばれる深刻な事態を引き起こす可能性もある。これは、すでに障害が発生しているサービスにさらに負荷をかけ、状況を悪化させることにもつながる。

このような連鎖的な障害を防ぎ、システムを安定稼働させるための効果的な設計パターンが「回路遮断器(サーキットブレーカー)パターン」である。これは電気回路のブレーカーのように機能し、ソフトウェアにおける回路遮断器は、あるサービスへのリクエストの失敗が事前に設定された閾値に達すると、そのサービスへのリクエストを一時的に「開いた」状態、つまりブロックする。ブレーカーが一度開くと、障害を起こしているサービスへの後続のリクエストは即座にブロックされ、実際にサービスへ問い合わせることはなくなる。これにより、障害中のサービスは回復するための時間を得ることができ、同時にシステム内の他の部分が障害に巻き込まれるのを防ぐことができる。そして、一定の「クールダウン期間」が経過した後、ブレーカーは自動的に「閉じた」状態に戻り、通常のトラフィックが再開される。

回路遮断器は、特に複数のサービスが連鎖的に呼び出されるようなパイプライン処理において非常に有用である。例えば、ECサイトのチェックアウト処理では、注文サービスと決済サービスの両方が必要となる。また、複数のマイクロサービスからデータを集約して表示するユーザープロフィールページなど、一つのサービスが障害を起こしただけで、連鎖する全てのリクエストが停止し、システム全体がダウンしてしまうリスクがあるシナリオで、回路遮断器は障害を局所化し、システム全体の停止を防ぐ役割を果たす。

この記事では、回路遮断器パターンが具体的にどのように機能するかを理解するため、簡単なデモアプリケーションを構築する。まず、Expressフレームワークを使用して、ユーザー情報、注文情報、支払い状況を取得する三つのエンドポイントを持つバックエンドAPIを作成する。注文と支払いのエンドポイントには、それぞれが失敗する確率を設定し、サービスの不安定な挙動をシミュレーションする。次に、Node.jsスクリプトでクライアント側のパイプラインを作成し、数秒ごとにユーザー、注文、支払い状況を順次取得し、結果を表示する。最初はJavaScript標準のfetch()関数を使って実装し、その後回路遮断器機能をサポートするライブラリに切り替えることで、システムの挙動の変化を比較して見ることができる。

回路遮断器を導入する前は、例えば支払いエンドポイントが常に失敗するように設定されている場合、クライアントは3秒ごとにそのエンドポイントに対して複数のリクエストを繰り返し送信し、全て失敗する様子が確認できる。このように、不安定なサービスに対して無駄なリクエストを送り続けることは、システムに不要な負荷をかけ、貴重なリソースを浪費してしまう。

パイプラインに回路遮断器を追加するには、ffetchというライブラリを利用する。このライブラリを使って、失敗回数の閾値やリセット期間などを設定したクライアントを作成し、元のfetch()呼び出しをこのクライアントの呼び出しに置き換える。これにより、特定のサービスへのリクエストが設定された回数連続で失敗すると、回路遮断器が「開いた」状態になる。ブレーカーが「開いた」状態の間は、そのエンドポイントへの後続のリクエストは実際にサーバーに送信されることなく即座に失敗として処理される。これにより、障害が発生しているサービスへの負荷が軽減され、回復のための時間が確保される。サーバー側のログでは、ブレーカーが「開いた」状態の間、クライアントからのリクエストログが一時的に途切れることが観察できるだろう。これは、回路遮断器が実際にリクエストの送信をブロックしている証拠である。この仕組みによって、不安定なサービスがシステム全体を巻き込むことなく、安定稼働を維持できるようになる。

回路遮断器には、さらに高度な「半開(Half-Open)」状態という概念も存在する。これは、ブレーカーが「開いた」状態から「閉じた」状態に戻るクールダウン期間の後に、少数の試行リクエストだけを許可する第三の状態である。この試行リクエストが成功すればブレーカーは完全に「閉じた」状態に戻るが、失敗すれば再び「開いた」状態に戻る。この半開状態は、クールダウン期間終了直後に全てのトラフィックが一斉にサービスに流れ込み、サービスを再び過負荷にしてしまう「サンダリング・ハード(thundering herd)」問題を防ぐのに役立つ。半開状態により、回復はより段階的かつ制御された方法で行われ、システムの安定性と回復速度を向上させる。ffetchライブラリは簡潔さのために開閉のみをサポートしているが、分散システムなどでの複雑な回復制御には半開状態が特に有効である。

結論として、回路遮断器パターンは、外部サービスに依存するシステムにおいて、障害発生時のシステムの安定性と回復力を高めるための実用的な設計パターンである。これは壊れたサービス自体を修正する万能薬ではないが、システムの予期せぬ停止を防ぎ、サービスがストレス下で予測可能な方法で劣化するように管理する上で非常に有効な手段である。この記事で構築したようなマルチエンドポイントのパイプラインでは、回路遮断器は一つの失敗しているサービスがシステム全体を巻き込んでダウンするのを防ぐのに大きく役立つだろう。

関連コンテンツ

関連IT用語

【ITニュース解説】Stop Hammering Broken APIs - the Circuit Breaker Pattern | いっしー@Webエンジニア