NetflixのHystrixにも使われるCircuit Breaker patternを調べてみた

Testing Strategies In A Microservice Architectureを読んだを読んでいる途中に出てきた、Circuit Breakerと呼ばれる機構を調べてみました。Martin Fowler氏がこの記事で言及しているものでした。

このCircuit Breaker patternは、Release It! 本番用ソフトウェア製品の設計とデプロイのためにで描かれているような、本番環境化において発生する、複数システムが関係するからこそ発生する障害を抑えることも目的としたデザインパターンのようです。「複数システムが関係するからこそ発生する障害」とは、一部システムの負荷が高まりタイムアウトするといったことを含みます。

内容自体は、 障害検出のための共有のオブジェクト(Circuit Breacker)を用意して、監視・検出できるようにする ということらしいです。NetflixのHystrixがその実装としてこのパターンを含んでいます。ちなみに、RubyだとここなんかがOSSの実装例として上がっていました。

Circuit Breacker Pattern

Circuit Breaker patternの考え方は単純で、以下の図のようにClientとSupplierの間にCircuit Breakder Objectを配置し、そのオブジェクトが障害のモニタリングを行いエラーを制御する、というものです。以下の図では、Circuit Breadker Objectが、Supplierのエラーを複数回検出すると、以降は復帰するまで必要以上にリクエストしないように制御します。

サンプルプログラムも置いていています。それを見ると、@failure_countのインスタンス変数にエラーの回数を足していき、一定数超えるとCircuit Openな状態にする。意図的にリセットされるとそのインスタンス変数がゼロになる、という処理で単純に書けますね。

Circuitの状態遷移は以下と定義されています。以下ではClose/Openの2値からさらにHalf Openというものも加え、Openな状態からresetされた後の復帰確認の状態を作っています。

この実装には、並列プログラムのデザインパターンであるFutures and promisesが良い知見を持っているそう。

Circuit Breakersのオブジェクトを設置することは、失敗するであろうオペレーションを抑制することができるところに価値があります。例えば、HTTPリクエストが30秒タイムアウトを繰り返す間、関連するサービスはそれを待たないといけないですが、そもそもCircuit Openな状態が既知であれば失敗することがわかっている処理に30秒も待つ必要がなくなるわけです。

締め

Breacker自体が障害になることもあるので、ClientはCircuit openな状態含めて適切な処理を実施する必要があります。一方で、Microservicesのような複数システムが連携する場合、監視・検出はシステムの品質を高めるために非常に重要な役割を担います。その仕組みを共通化してライブラリとして用意しておくことは価値が高そうです。

1 Comment

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.