Node.js のサーキット ブレーカー メカニズムの詳細な分析

青灯夜游
リリース: 2021-10-18 09:53:55
転載
2061 人が閲覧しました

この記事では、Node.js のサーキット ブレーカー メカニズムについて説明します。お役に立てば幸いです。

Node.js のサーキット ブレーカー メカニズムの詳細な分析

アーキテクチャの進化による問題

従来の CS アーキテクチャを使用すると、障害などの理由でサーバーがリクエストをブロックし、お客様がクライアントのリクエストは応答を失い、その結果、ユーザーのグループは一定期間後にサービスを取得できなくなります。この状況によって考えられる影響は限定的であり、推定することができます。

ただし、マイクロサービス システムでは、サーバーが他のいくつかのマイクロサービスに依存している可能性があり、これらのマイクロサービスはさらに他のマイクロサービスに依存している可能性があります。この場合、特定のサービスがダウンストリームの輻輳を引き起こす可能性があり、致命的な結果を引き起こす可能性があります。瞬間的 (数秒以内) のカスケード的なリソース消費により、リンク全体が停止します。これを「サービス崩壊」と呼びます。 [推奨される学習: 「nodejs チュートリアル 」]

Node.js のサーキット ブレーカー メカニズムの詳細な分析

Node.js のサーキット ブレーカー メカニズムの詳細な分析

#問題を解決するためのいくつかの方法

    #ヒューズモード: 名前が示すように、家庭用回路と同じように、ラインの電圧が高すぎるとヒューズが切れて火災を防ぎます。サーキットブレーカーモードを使用するシステムでは、上流のサービス呼び出しが遅い、またはタイムアウトが多いことが判明した場合、サービス呼び出しは直接終了され、情報が直接返され、リソースが解放されます。素早く。アップストリーム サービスが改善されるまで、通話は再開されません。
  • 分離モード: さまざまなリソースまたはサービスへの呼び出しをいくつかの異なるリクエスト プールに分割します。1 つのプール内のリソースが使い果たされても、他のリソースへのリクエストには影響せず、シングル ポイントを防ぎます。障害によりすべてのリソースが消費されます。これは非常に伝統的な災害復旧設計です。
  • 電流制限モード: サーキットブレーカーと絶縁はどちらも後処理方法であり、電流制限モードでは問題が発生する前にその可能性を低減できます。電流制限モードでは、特定のサービスのリクエストに対して最大 QPS しきい値を設定でき、しきい値を超えたリクエストは直接返され、処理用のリソースを占有しなくなります。ただし、電流制限モードではサービス崩壊の問題を解決することはできません。サービス崩壊は多くの場合、多数のリクエストによってではなく、複数のカスケード層の増幅によって引き起こされるためです。
  • サーキット ブレーカーのメカニズムと実装

サーキット ブレーカーの存在は、保護層を提供することに相当します。サービスとリソースの場合、サーキット ブレーカーはこれらのエラーを監視し、特定のしきい値に達するとリクエストを失敗させることで、リソースの過剰な消費を防ぐことができます。また、サーキットブレーカーはサービスの状態を自動的に認識して復旧する機能も備えており、上流サービスが正常に戻った場合には、サーキットブレーカーが自動的に判断して通常のリクエストを再開することができます。

サーキット ブレーカーを使用しないリクエスト プロセスを見てみましょう: ユーザーは ServiceA に依存してサービスを提供し、ServiceA は ServiceB によって提供されるサービスに依存します。この時点で ServiceB が失敗すると仮定します。10 分以内、リクエストごとに、応答に 10 秒の遅延が発生します。

Node.js のサーキット ブレーカー メカニズムの詳細な分析つまり、N 人のユーザーが ServiceA のサービスをリクエストしているとします。ServiceB へのリクエストが一時停止されるため、数秒以内に ServiceA のリソースが消費されます。ユーザーからのその後のリクエストを拒否します。ユーザーにとって、これは ServiceA と ServiceB の両方が同時に失敗し、サービス リンク全体が崩壊したことを意味します。

そして、ServiceA にサーキット ブレーカーを設置するとどうなるでしょうか?

    障害の数が特定のしきい値に達すると、サーキット ブレーカーは ServiceB へのリクエストが無効であると判断します。この時点では、ServiceA は ServiceB をリクエストし続ける必要はありませんが、直接失敗を返すか、他のフォールバックからのバックアップ データを使用します。この時点で、サーキットブレーカーは
  • 開回路

    状態になります。

  • 一定の時間が経過すると、サーキット ブレーカーは ServiceB が復旧したかどうかを定期的に問い合わせ始めます。この時点では、サーキット ブレーカーは
  • 半開##になっています。 # 州。

    ServiceB が復旧すると、サーキット ブレーカーは
  • closed
  • 状態になり、このとき ServiceA は通常どおり ServiceB を呼び出し、結果を返します。

サーキットブレーカーのステータス図は次のとおりです。 Node.js のサーキット ブレーカー メカニズムの詳細な分析

次のことが考えられます。いくつかの核心点は次のとおりです: Node.js のサーキット ブレーカー メカニズムの詳細な分析

タイムアウト: 要求が失敗を引き起こすまでの時間制限
  • 失敗のしきい値: つまり、サーキット ブレーカーが開回路をトリガーします。以前は、必要な障害の数
  • #再試行タイムアウト: サーキット ブレーカーが開回路状態にある場合、要求を再試行する、つまり半開状態に入るまでにどのくらいの時間がかかりますか

この知識をもとに、サーキット ブレーカーの作成を試みることができます:

class CircuitBreaker {
  constructor(timeout, failureThreshold, retryTimePeriod) {
    // We start in a closed state hoping that everything is fine
    this.state = 'CLOSED';
    // Number of failures we receive from the depended service before we change the state to 'OPEN'
    this.failureThreshold = failureThreshold;
    // Timeout for the API request.
    this.timeout = timeout;
    // Time period after which a fresh request be made to the dependent
    // service to check if service is up.
    this.retryTimePeriod = retryTimePeriod;
    this.lastFailureTime = null;
    this.failureCount = 0;
  }
}
ログイン後にコピー

サーキット ブレーカーのステート マシンを構築します:

async call(urlToCall) {
    // Determine the current state of the circuit.
    this.setState();
    switch (this.state) {
      case 'OPEN':
      // return  cached response if no the circuit is in OPEN state
        return { data: 'this is stale response' };
      // Make the API request if the circuit is not OPEN
      case 'HALF-OPEN':
      case 'CLOSED':
        try {
          const response = await axios({
            url: urlToCall,
            timeout: this.timeout,
            method: 'get',
          });
          // Yay!! the API responded fine. Lets reset everything.
          this.reset();
          return response;
        } catch (err) {
          // Uh-oh!! the call still failed. Lets update that in our records.
          this.recordFailure();
          throw new Error(err);
        }
      default:
        console.log('This state should never be reached');
        return 'unexpected state in the state machine';
    }
  }
ログイン後にコピー

残りの関数を補足します:

// reset all the parameters to the initial state when circuit is initialized
  reset() {
    this.failureCount = 0;
    this.lastFailureTime = null;
    this.state = 'CLOSED';
  }

  // Set the current state of our circuit breaker.
  setState() {
    if (this.failureCount > this.failureThreshold) {
      if ((Date.now() - this.lastFailureTime) > this.retryTimePeriod) {
        this.state = 'HALF-OPEN';
      } else {
        this.state = 'OPEN';
      }
    } else {
      this.state = 'CLOSED';
    }
  }

  recordFailure() {
    this.failureCount += 1;
    this.lastFailureTime = Date.now();
  }
ログイン後にコピー

サーキット ブレーカーを使用する場合、リクエストをラップするだけです。サーキット ブレーカー インスタンスの Call メソッドで呼び出すだけです。

...
const circuitBreaker = new CircuitBreaker(3000, 5, 2000);

const response = await circuitBreaker.call('http://0.0.0.0:8000/flakycall');
ログイン後にコピー

成熟した Node.js サーキット ブレーカー ライブラリ

Red Hat

Opossum## と呼ばれる昔に作成された # 成熟した Node.js サーキット ブレーカー実装。リンクはここにあります: Opossum。分散システムの場合、このライブラリを使用すると、サービスの耐障害性が大幅に向上し、サービス障害の問題を根本的に解決できます。

元のアドレス: https://juejin.cn/post/7019217344601948173

著者: ES2049 / Singularity を探しています

プログラミング関連の知識をさらに増やす 、
プログラミングビデオ

にアクセスしてください。 !

以上がNode.js のサーキット ブレーカー メカニズムの詳細な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:juejin.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート