4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

opossumでサーキットブレーカーを実装する(1)

Posted at

概要

node.jsでサーキットブレーカーパターンを実装したライブラリ「opossum」の利用方法メモです。
バージョンはv5.0.0です。

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

外部システムやあるリソースと連携した処理を行う箇所にサーキットブレーカーパターンを入れておくと以下のような事が実現できます。

  • 外部システム/リソースに障害が発生してエラーが多発する場合は、要求された処理を実行しない/処理数を制限する
  • 外部システム/リソースがが正常処理できるようになった場合は、正常運転に戻す

具体的には外部システムの障害によってレスポンス遅延などが発生した場合には、リクエスト送信を遮断して連鎖的な発生を防ぐ。または、キャパシティを超えるリクエスト送信を制限してシステム全体のパフォーマンス劣化を防ぐ事ができます。

なので何か障害とか突発的なリクエストが発生した時に、慌てずにすみます、、。
(外部システムとの連携のお話だとネットワークの問題なのでアプリで実装せず、サービスメッシュで対応というのが今どきなんでしょうか)

サーキット ブレーカー パターン - Cloud Design Patterns | Microsoft Docs
https://docs.microsoft.com/ja-jp/azure/architecture/patterns/circuit-breaker

##状態遷移
サーキットブレーカーは、「クローズ」、「オープン」と「ハーフオープン」の3つの状態があり、状態によって要求された処理の実行をする/しないが決定されます。
ざっくり書くと下記のような感じです。

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

  • クローズ(close)

    • サーキットブレーカーの初期状態
    • この状態の時は要求された処理が実行される。
    • 実行した結果、エラーが発生してしきい値を超えると「オープン」状態に遷移
  • オープン(open)

    • この状態の時は、要求された処理を実行せずフォールバック処理が実行される
    • 指定した時間が経過すると「ハーフオープン」状態に遷移する
  • ハーフオープン(half open)

    • この状態の時も要求された処理を実行します。
    • 実行した結果、成功した回数がしきい値に達すると正常な状態に回復したとみなして「クローズ」に遷移します。
    • この状態の時にエラーが多発したら「オープン」に遷移します。

opossum

githubで「circuit breaker」で言語をJavascriptにして検索して上位にあった「opossum」というサーキットブレーカーパターンの実装を試してみたいと思います。

nodeshift/opossum: Node.js circuit breaker - fails fast ⚡️
https://github.com/nodeshift/opossum

opossumはサーキットブレーカーパターンを組み込みたい処理を非同期な関数にして渡してやれば、にネットワークアクセスだろうが、リソースの読み書きだろうが何でも利用できます。

利用方法

オプションは省きますが最低限のサンプルは下記のようになります。
(サンプルの非同期関数は引数に"OK"を渡した時だけ成功するようになっています。)

  • サーキットブレーカーの対象となる非同期関数を実装する。
  • opossumに引数で実装した非同期関数を渡す
  • fallbackで非同期関数でエラーが発生した場合の処理を実装
  • fireで非同期関数の実行

const CircuitBreaker = require('opossum');

// サーキットブレーカーの対象となる非同期関数を実装
const asyncFunction = (arg) => {
  return new Promise((resolve, reject) => {
    arg === 'OK' ? resolve(`${arg}!!!`) : reject();
  });
};

// opossumに引数で実装した非同期関数を渡す
const circuit = new CircuitBreaker(asyncFunction);

// fallbackで非同期関数でエラーが発生した場合の処理を実装
circuit.fallback((arg) => {
  return `${arg}!!!`
});

(async () => {
  const ret = await Promise.all([
    circuit.fire("OK"),
    circuit.fire("NG"),
    circuit.fire("OK")
  ]);
  console.log(ret);
})();

実行結果は以下のようになります


[ 'OK!!!', 'NG!!!', 'OK!!!' ]

#次回
次回で、opossumのオプションを指定して下記のようなケースでの利用方法を試してみます。

  • 同時実行数が想定したキャパシティを超えそうな場合は処理数を抑制して、キャパシティ超えを防ぐ
  • 外部システムで障害が起こった場合に、リクエストを送信しないでフォールバック処理を行う

###We're hiring!
AIチャットボットを開発しています。
ご興味ある方はWantedlyページからお気軽にご連絡ください!

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?