サーキットブレーカーパターンの仕組み
サーキットブレーカーって、あの電気のブレーカーと関係あるの?
まさにその電気のブレーカーがモデルだよ。家で電気を使いすぎるとブレーカーが落ちて回路を遮断するよね。ソフトウェアのサーキットブレーカーパターンも同じ発想で、呼び出し先のサービスが調子悪いときにリクエストを遮断して、障害が広がるのを防ぐ仕組みなんだ。
障害が広がるってどういうこと?
たとえばマイクロサービスで、サービスAがサービスBを呼んで、BがCを呼んでいるとする。Cがダウンしたとき、Bは何度もCを呼んで待ち続けるよね。するとBも遅くなって、最終的にAも巻き込まれて全部止まる。これがカスケード障害(障害の連鎖)だよ。
全部止まっちゃうのは怖いね…。サーキットブレーカーはどうやって防ぐの?
サーキットブレーカーには3つの状態があるんだ。まず「Closed(閉)」は通常運転で、リクエストがそのまま通る。失敗が一定回数を超えると「Open(開)」に切り替わって、リクエストを即座にブロックする。しばらく待ってから「Half-Open(半開)」になって、少しだけ試しにリクエストを通す。成功すればClosedに戻るし、失敗すればまたOpenに戻るんだよ。
Openのときはリクエストが全部ブロックされるの?ユーザーにはどう見えるの?
なるほど!でも、いつOpenに切り替えるかはどうやって決めるの?
失敗しきい値とタイムアウトを設定するんだ。たとえば「直近10回のリクエストで5回失敗したらOpenにする」「Openになったら30秒間ブロックしてからHalf-Openにする」みたいにね。この値はサービスの特性に合わせてチューニングするのが重要だよ。
実際にコードで使うときはどうするの?自分で書くのは大変そう…。
Netflixが作ったんだ!さすが大規模サービスだね。
Netflixは何百ものマイクロサービスを運用していて、Hystrixで障害の連鎖を防いでいたんだ。ただ、今はIstioなどのサービスメッシュ側でサーキットブレーカーを実装する流れに移っていて、アプリケーションコードから切り離す方向に進んでいるよ。
サーキットブレーカーの状態って、運用中にどうやって確認するの?
モニタリングが超重要だよ。Openに切り替わった回数、Half-Openでの成功率、フォールバックの発生頻度をダッシュボードで可視化するのが定石。サーキットブレーカーが頻繁にOpenになるなら、呼び出し先のサービス自体を修正すべきサインだからね。
リトライと組み合わせたりもするの?
いい質問だね。リトライ、タイムアウト、サーキットブレーカーは3点セットで考えるのが基本だよ。まずタイムアウトで1回の待ち時間を制限して、失敗したら数回リトライして、それでもダメならサーキットブレーカーが開いて全体を守る。ただしリトライとサーキットブレーカーの設定が噛み合ってないと、リトライが失敗カウントを一気に増やしてすぐOpenになっちゃうから注意が必要だよ。
他にも似たパターンってあるの?
バルクヘッドパターンという補完的な仕組みがあるよ。船の隔壁(バルクヘッド)と同じ発想で、スレッドプールや接続プールをサービスごとに分離するんだ。サーキットブレーカーが「壊れたサービスへの呼び出しを止める」のに対して、バルクヘッドは「壊れたサービスがリソースを食い尽くすのを防ぐ」。両方組み合わせると、マイクロサービスの耐障害性がグッと上がるよ。