すごいよ、サーキットブレーカー! 〜 マイクロサービスアーキテクチャの設計パターン 〜

Tech

サーキットブレーカーは、無数のサービスのネットワークで構成されるマイクロサービスアーキテクチャにはなくてはならない機構です。 本記事では、サーキットブレーカーに関して、できるだけわかりやすく説明していきたいと思います。

サーキットブレーカーとは?

サーキットブレーカーの概要

サーキットブレーカーは、マイクロサービスのように、サービス同士が接続しあい、複雑なネットワークを構成する際に、局所的な障害がシステム全体に波及させない、仕組みです。 ブレーカー(Breaker)を落とすように、ネットワーク上の回路(Circuit)を遮断するのです。

マイクロサービスにおけるカスケード障害の連鎖の問題

カスケード障害(cascading failure)とは、ネットワークの一部の障害が要因となり,連鎖的に障害がシステム全体へ波及する現象のことを指します。 マイクロサービスアーキテクチャにおいては、サービス同士が接続しあい、複雑なネットワークを構成しています。 そのため、このカスケード障害に関しての対処は必要となります。

カスケード障害の様子を段階を追って説明します。

(1) 各サービスが正常に動作している

各サービスが協調して動作して、利用者に価値を届けています。マイクロサービスアーキテクチャ最高!という感じですね。

f:id:fujiyamaegg:20200613100238p:plain各サービスが正常に動作している

(2) ひとつのサービスがダウン!

ひとつのサービスがダウンしてしまいます。ダウンしたサービスを利用しているサービスは、相手からの応答がない状態で待ちが発生してしまいます。

f:id:fujiyamaegg:20200613100320p:plainひとつのサービスがダウン

(3) ダウンしたサービスを利用しているサービスのリソース不足が発生

ダウンしたサービスを利用しているサービス内では、待ちが発生し、段々と外部からのリクエストも滞留していきます。そうなると、リソースがどんどん消費されていってしまいます。このサービスも危険水域に!

f:id:fujiyamaegg:20200613100509p:plainダウンしたサービスを利用しているサービスのリソース不足が発生

(4) 遂にダウンの連鎖!

ダウンしたサービスを利用するサービスもついにはダウンしてしまいました。そのサービスを利用している別のサービスも危険水域に。障害が連鎖していく!

f:id:fujiyamaegg:20200613100833p:plain遂にダウンの連鎖!

(5) 障害はネットワーク全体に広がる

障害は次々に連鎖していく、ネットワーク全体に障害が広がっていきます。このようになってしまうと、システム全体が利用できなくなり、被害も甚大になっていきます。

f:id:fujiyamaegg:20200613101141p:plain障害はネットワーク全体に広がる

このように、最初は局所的な問題が、徐々に他のノードに伝播し、最終的にはネットワーク全体に大きな被害をもたらすことを、カスケード障害というのです。

サーキットブレーカーによるソリューション

このような恐ろしいカスケード障害を防ぐため、「障害の分離」(Fault Isolation)が必要になります。その方法のひとつがサーキットブレーカーなのです。 サーキットブレーカーは、サービス間の接続を回路(circuit)とみなし、通信相手のサービスの様子がおかしくなったら、ブレーカー(breaker)を落とすように、そのサービスへのリクエストをストップします。そのことにより、外部からのリクエストを滞留せずに処理できるため、リソース不足にも陥ることなく、障害の連鎖を止めるのです。

サーキットブレーカーの様子を説明します。

(1) 正常に動作している時、回路は閉じている

サービスが正常に動作しているときは、回路(circuit)は、閉じています。これをサーキットブレーカーでは、「Closed」状態と呼びます。

f:id:fujiyamaegg:20200613103717p:plain正常に動作。Closed状態

(2) 障害発生でサーキットブレーカー発動

使用しているサービスに障害が発生して、応答状態が悪くなると、サーキットブレーカーを発動します。このとき、回路は、「Open」状態になります。この状態の時には、外部から受けたリクエストに対して素早くレスポンスを返します。このレスポンスの内容は、以下のようなものが考えられます。

  • エラー
  • デフォルトのデータ
  • キャッシュしているデータ

f:id:fujiyamaegg:20200613103907p:plainサーキットブレーカー発動。Open状態へ

3つの状態による管理

サーキットブレーカーでは、「Open」、「Closed」の状態を扱うと記載しましたが、実はもうひとつ状態があります。 それが、「Half-Open」という状態です。 この状態は、「Open」から「Closed」の状態に戻る際の中間に位置する「お試し期間」です。 各状態をまとめると、以下のようになります。

  • Closed: データを流す、通常の状態。
  • Open: サーキットブレーカーが発動され、回路が開いている状態。つまり、データが流れないようになっている。
  • Half-Open: 「Open」状態から「Close」状態に戻る、途中の段階。

正常に動作している「Closed」状態を起点に状態遷移を考えてみましょう。

  • リクエストが失敗する回数が増えていき、事前に設定した閾値を超えるとサーキットブレーカーが発動され「Open」の状態に遷移します。
  • 「Open」の状態になると、タイマーを動作させます。その期間中、相手サービスにはリクエストを投げずに、素早く処理をしていきます。
  • タイマー満了になると、「Half-Open」状態に遷移します。ここでは、すべてのリクエストを通すのではなく、少量のリクエストを相手サービスに投げてみて、その成功回数が一定回数を超えると、復旧したとみなして「Closed」状態に遷移します。

状態遷移図にすると、以下のようになります。

f:id:fujiyamaegg:20200613111338p:plainサーキットブレーカーの状態

名前の由来

サーキットブレーカー パターンは、Michael T. Nygardの「Release It!」という書籍で紹介され、広まったといわれています。 「安定性のパターン」で「ブレーカー」(原書では 「Circuit Breaker」)として紹介されています。

[Release It! 本番用ソフトウェア製品の設計とデプロイのために] (https://amazon.co.jp/dp/4274067491/ref=cm_sw_r_tw_dp_U_x_EBm1EbPK703ZC)

サーキットブレーカー実装は

サーキットブレーカーのライブラリ実装としては、Netflix 社の Hystrix(現在は開発終了している模様)、resilience4jがあります。何れもJavaで実装されています。

また、サーキットブレーカーをサービスメッシュにおけるプロキシの中で実装しているものもあります。 有名なところでは、Envoyとなります。

サーキットブレーカーの何がすごいのか?

障害の連鎖を食い止めてくれる

ネットワーク上で発生した局所的な障害を、ネットワーク全体に波及するのを食い止めてくれる。 これは、数多くのサービスによって構成されているマイクロサービスアーキテクチャにおいては、とても重要な機能です。

障害からの復旧も徐々におこなってくれる

サーキットブレーカーでは、「Half-Open」という、いわば「試用期間」を設けることで、障害からの復旧を無理なく行うようにしています。これは、「リハビリ期間」ととらえることも可能だと思います。 いきなり、リクエストをガンガン投げつけることで、復旧の妨げになってしまうのを避けるのです。 人間でも、メンタル疾患で休職していた人が復職する際、最初は半日勤務、次の段階でもう少し勤務時間を増やして、そして最後にフルタイムに戻る、ということと同じですね。

これからのサーキットブレーカーは?

サーキットブレーカーの基本的な制御は、3つの状態「Open」、「Closed」、「Half-Open」の遷移にて行います。これらの状態が遷移する条件は、失敗数や成功数の閾値を基準に行われます。この閾値を具体的にどのような値にするかは、非常に難しいと思います。実際に動かしてみないと最適な値は見つけっれないのでは?と思います。こういったことは、AIが得意とする分野だと思います。AIが勝手に最適な閾値をみつけて、勝手に動作すると、管理者が非常に楽になると思います。

結局、サーキットブレーカーとは?

サーキットブレーカーは、ネットワーク全体に甚大な被害をもたらしかねないカスケード障害を食い止める、設計パターンです。 マイクロサービスアーキテクチャには、なくてはならない機構です。

参考

タイトルとURLをコピーしました