RPC フレームワーク Surface Classic 5 についての詳細な考察: RPC ヒューズの電流制限、RPC 多重化接続メカニズム

11 RPC フレームワークは電流制限とヒューズをどのように実装しますか

おすすめ記事:RPC実装原理のコア技術「限流ヒューズ」

11.1 Dubbo がサービス フローを制限する必要があるのはなぜですか? (根本的な原因は、サーバーが自分自身を保護することです)

電流制限は一般的なシステム保護方法です。分散システムやマイクロサービス アーキテクチャでは、インターフェイスを過度に使用すると、CPU、メモリ、帯域幅などのリソースの過負荷がボトルネックになる可能性があります。システムのクラッシュを回避し、システムの可用性を確保し、すべてのユーザーに公平かつ合理的なサービスを提供するには、インターフェイスのトラフィックを制限する必要があります。

Dubbo は高性能 Java RPC フレームワークであり、通常、同時実行性の高い大規模な分散システムを構築するために使用されます。この環境では、適切なスロットリングが実装されていない場合、1 つのサービスのトラフィック フローが突然増加し、システム全体がダウンする可能性があります。したがって、Dubbo はバックエンド サービスを過剰なリクエストから保護するために電流制限機能を提供する必要があります。

11.2 dubbo のフェイルオーバー戦略とヒューズメカニズムの違い

Apache Dubbo は、サービス検出、サービス負荷分散、サービス呼び出し、サービス フォールト トレランスなど、多くのマイクロサービス関連機能を提供する、高性能かつ軽量のオープン ソース Java サービス フレームワークです。Dubbo では、フェイルオーバー戦略とヒューズ メカニズムはどちらもサービスのフォールト トレランスの手段ですが、実装と目標が異なります。

  1. フェイルオーバー戦略 (フェイルオーバー) :

    • サービス呼び出しで例外が発生した場合は、呼び出すことができるサービス プロバイダーを再選択してください。
    • Dubbo のデフォルト戦略はフェイルオーバーです。つまり、呼び出しが失敗した場合に他のプロバイダーを再試行します。
    • 再試行回数は Dubbo で設定でき、デフォルトは 2 回の再試行 (合計 3 回の呼び出し) です。
  2. ヒューズ機構:

    • ヒューズ メカニズムは、より高度な保護戦略であり、サービスで異常が継続する場合、または応答時間が長すぎる場合、システムはこれらの異常なサービス コールを自動的に「切断」して、システムの雪崩を防ぎます。
    • Dubbo 自体にはヒューズが組み込まれていませんが、Hystrix や Sentinel などの外部ヒューズ ライブラリと統合できます。
    • ヒューズ メカニズムは、特定の時間枠内のサービスの呼び出しを監視します。失敗率が特定のしきい値を超えると、ヒューズが自動的に開きます。この時点で、このサービスへのすべての呼び出しは直接拒否され、渡されません。実際のサービスプロバイダーに。所定の回復時間が経過すると、ヒューズが半開状態になり、一部のリクエストの呼び出しが可能になり、これらのリクエストが成功すると、ヒューズが閉じてシステムは通常の状態に戻ります。

違い

  1. アプリケーション シナリオ: フェールオーバーは時折発生する単一の呼び出しエラーを目的とし、ヒューズ メカニズムは継続的なサービス障害や応答の遅さを目的としています。
  2. 応答方法: フェイルオーバーは、他のプロバイダーを再試行することでサービス コールの失敗に対処し、サーキット ブレーカーは、サービス コールを拒否することでサービスの不安定に対処します。
  3. 目標: フェイルオーバーはサービス呼び出しの成功を保証するように設計されており、サーキット ブレーカーは持続的なエラーや応答の遅さからシステムを保護するように設計されています。

一般に、これら 2 つの戦略はマイクロサービス アーキテクチャで非常に役立ち、実際のシナリオと要件に応じて適切な戦略を選択して、システムの安定性と信頼性を向上させることができます。

11.3 Dubbo のサービスの電流リミッターと、dubbo を使用してリクエストを受信する上位層サービスの電流リミッターの違いは何ですか? ダボ電流制限器が使用されており、上位層アプリケーションは追加の電流制限ポリシーを構成する必要はありませんか?

Dubbo のサービス フロー制限は、主にサービス コールのレベルを対象としており、その目標は、同時実行性の高い環境において、システム内のマイクロサービス コールが事前に設定されたしきい値を超えないようにして、システムの安定性を確保することです。RPC 呼び出しの頻度に基づいて制限されます。

上位層のサービス (API ゲートウェイや Web アプリケーションなど) は、主にユーザーからの HTTP リクエストなどの外部リクエストのフローを制限します。この調整は、IP アドレス、ユーザー ID、API キーなどのさまざまなポリシーに基づいて行うことができます。

Dubbo が内部サービスのレート制限を提供している場合でも、上位層のアプリケーションは依然としてレートを制限する必要がある場合があります。その理由は次のとおりです。

上位層アプリケーションが直面するトラフィックのタイプは、Dubbo サービスのトラフィックとは異なります。Dubbo はサービス間の RPC 呼び出しを処理しますが、上位層アプリケーションは外部 HTTP リクエストを処理する必要がある場合があります
上位層アプリケーションには、ビジネス ロジックに基づく特定の制限など、他のフロー制限要件がある場合があります。

上位層のアプリケーション定義の電流リミッタが http インターフェイスに対してのみ有効な場合、つまり、リクエストが rpc プロトコルに基づいている可能性があり、ユーザー定義の電流リミッタはそれを制限できません。同様に、rpc 呼び出しのみを処理する電流リミッターの場合、外部 http 要求からのトラフィックを制限することはできません。

したがって、さまざまな電流制限措置を講じて、さまざまなリクエストのトラフィックを分離できます。マイクロサービス システムからのリクエストの場合、すべてのトラフィックは rpc フレームワークの電流リミッターを通過し、外部 http ユーザーからのリクエストの場合は、アプリケーション定義の制限を通過します。 . ストリーマー。

したがって、Dubbo の電流制限器が使用されている場合でも、上位層アプリケーションは、さまざまなニーズや考慮事項を満たすために独自の電流制限戦略を構成する必要がある場合があります。

11.4 Dubbo のサービスに対する電流リミッターと、ユーザーがサービスにアクセスするための電流リミッターの違いは何ですか?

サービスのスロットリング: これは主に、サービスまたはメソッドの呼び出し頻度を制限します。たとえば、サービス メソッドの呼び出し数が 1 秒あたり 100 に制限されている場合があります。このような制限は主にシステム容量とパフォーマンスの考慮事項に基づいています。

ユーザー アクセス サービス リミッター: これは、各ユーザーまたは呼び出し元によるサービスへのアクセス数に基づいています。たとえば、API は各ユーザーを 1 秒あたり 10 リクエストに制限する場合があります。このような制限は通常、API の不正使用の防止などのビジネス ニーズに基づいています。

11.4.1 ここでのダボ サービス フロー制限は、ユーザーのフローも制限しますか?

Dubbo サービスの電流制限は、ユーザー トラフィックに直接適用されるものではなく、サービス呼び出しに基づいています。ただし、外部ユーザーのリクエストが複数のサービス間呼び出しにつながる場合、Dubbo の現在の制限戦略がユーザーのリクエストに間接的に影響を与える可能性があります。たとえば、ユーザー リクエストがサービス A をトリガーし、サービス A がサービス B を呼び出す必要がある場合、サービス B のトラフィック制限ポリシーがユーザー リクエストの処理速度や結果に影響を与える可能性があります。

11.4.2 ユーザーがサービス B を直接呼び出した場合、ユーザーのリクエストの処理速度に影響しますか?

もちろん。ユーザーがサービス B を直接呼び出し、サービス B に Dubbo のサービス レート制限ポリシー設定がある場合、このレート制限ポリシーは、他のサービスから転送されたかユーザーから直接転送されたかに関係なく、サービス B に対するすべての呼び出しリクエストに対して有効になります。

つまり、サービス B のレート制限ポリシーが 1 秒あたり 100 リクエストを処理するように設定されている場合、リクエストの呼び出し頻度がこの制限を超えると、これらのリクエストがユーザーから直接送信されたものであるか、他のサービスから送信されたものであるかに関係なく、レート制限ポリシーを超過します。処理が拒否または遅延されます。

したがって、ユーザーがサービス B を直接呼び出す場合、リクエスト量がサービス B のスロットルしきい値を超えると、実際にユーザーリクエストの処理速度に影響を与えたり、リクエストが拒否される可能性があります。

11.5 Dubbo はサービス トラフィックをどのように制限しますか?

11.5.1 Dubbo はどのような電流制限戦略を提供しますか?

Dubbo は、トークン バケット、カウンターなどを含むさまざまな電流制限戦略を提供します。具体的な方法は以下の通りです。

  • トークン バケット アルゴリズムに基づく: Dubbo は、電流制限にトークン バケット アルゴリズムを使用できます。このアプローチでは、定期的にトークン バケットにトークンが追加され、各リクエストにはバケットからのトークンが必要です。バケット内にトークンがない場合、リクエストは拒否されます。
  • カウンタベース: Dubbo はカウンタを維持できます。新しいリクエストがあるたびに、カウンタは 1 ずつ増分され、しきい値を超えると新しいリクエストは拒否されます。エラーが 1 秒を超えないと予想される場合、カウンタは1秒ごとにリセットされます
  • クラスター電流制限: Dubbo はクラスター全体の電流制限をサポートします。この場合、調整ポリシーは複数のサービス プロバイダー間で共有されます。
  • フィルターを通じて実現: Dubbo の電流制限機能はカスタム フィルターを通じて実現でき、ユーザーに高度な柔軟性を提供します。
  • リーキーバケット: サービスのプロバイダーを保護でき、サービスコンシューマーは適切なレートでプロバイダーにトラフィックを送信します。

Dubbo の電流制限構成はサービス プロバイダー側​​とコンシューマ側の両方で設定できるため、優れた柔軟性が得られることに注意してください。ただし、レート制限ポリシーを構成する場合は、レート制限ルールが過度に制限されたり、過度に緩和されたりしないように注意する必要があります。

11.5.2 ダボ電流リミッタの粒度はどれくらいですか?

Dubbo では、電流制限の一般的な粒度は次のとおりです。

  1. グローバル電流制限:

    • Dubbo サービス全体の全体的な TPS (1 秒あたりのトランザクション数) を制限します。
    • たとえば、サービスが複数のインスタンスをデプロイする場合、グローバル レート リミッタによってすべてのインスタンスの全体的な TPS が制限されます。
  2. サービスインターフェースレベルの電流制限:

    • 特定のサービス インターフェイスのフローを制限します。
    • OrderServiceたとえば、 oneと one がある場合、金銭的な取引が含まれる可能性があるため、ペアに対してより厳格な調整ルールを設定することUserServiceができます。OrderService
  3. サービスメソッドレベルの電流制限:

    • 同じサービス インターフェイスでも、メソッドが異なれば、処理負荷やビジネスの重要性も異なります。したがって、Dubbo は特定のメソッドの電流制限をサポートします。
    • たとえば、 ではOrderService、メソッドにはメソッドよりも厳しい電流制限要件があるcreateOrder場合があります。getOrderStatus
  4. コンシューマ/プロバイダーのスロットル:

    • コンシューマーまたはプロバイダーに固有のスロットルを設定できます。このようにして、コンシューマが大量のリクエストを送信する可能性があることがわかっている場合、そのコンシューマに対して特定のスロットル ルールを設定できます。
  5. アプリケーションレベルの電流制限:

    • 呼び出し元に基づいてスロットルを適用します。たとえば、内部アプリケーションはより多くのリクエストの送信を許可されますが、外部アプリケーションはより制限される場合があります。

Dubbo では、電流制限を実現する手段は主にフィルタ (Filter) メカニズムに依存します。一般的な電流制限アルゴリズムには、トークン バケット、リーキー バケットなどが含まれます。オープンソース コミュニティでは、 や などのライブラリがSentinelDubboHystrixと一緒に使用されることが多く、より強力で柔軟な電流制限、回路遮断、およびダウングレード機能を Dubbo に提供します。

実際の使用では、トラフィック制限ポリシーは、サービスのビジネス特性、システムのボトルネック、およびサービスの SLA (サービス レベル アグリーメント) 要件に応じて合理的に構成および調整される必要があります。

11.7 マルチレベル電流制限戦略? dubbo サービス電流リミッター、ビジネス電流リミッター、ゲートウェイ電流リミッター、nginx 電流リミッター

OpenFeign の RPC および HTTP リミッター:

はい、OpenFeign は HTTP ベースの RPC フレームワークです。リクエストのルーティングに Spring Cloud Gateway などの API ゲートウェイを使用する場合、通常、これらのゲートウェイには独自のレート リミッターが含まれます。HTTP リクエストがこれらのゲートウェイに到着すると、まずレート リミッターによって処理されます。

リクエストがスロットルを通過してターゲット サービスにルーティングされると、それらのサービスには OpenFeign またはその他のテクノロジに基づく独自の内部スロットル ポリシーが設定される場合もあります。したがって、ゲートウェイ レベルとサービス レベルの 2 つのレベルのスロットルを設定できます。

これら 2 つのレベルの電流制限は相補的です。ゲートウェイ レベルの調整は主に、システム全体の安定性と、サービスにリクエストが殺到するのを防ぐことに関係しています。サービス レベルの電流制限は、特定のユーザーまたはクライアントに提供される QoS (サービス品質) などのサービスのビジネス ロジックに重点を置いています。

つまり、特定のビジネス ニーズやシステム アーキテクチャに応じて、さまざまなレベルの電流制限を多重化したり、個別に構成したりすることができます。

11.8 ダボはなぜサービスのダウングレードと融合を実行するのでしょうか?また、誰を対象としていますか?

Dubbo は、サービスのダウングレードと融合を実行して、システムの堅牢性と安定性を確保します。これら 2 つのメカニズムは、システムが特定の異常な状態や過負荷に直面した場合でも、サービスを完全に中断するのではなく、制限された、場合によっては低下したサービス品質を提供し続けるのに役立ちます。Dubbo のサービス ダウングレードとサーキット ブレーカーは、主にサービスの利用者とプロバイダーを対象としています。

  1. サービスのダウングレード:

    • 目的システムの高負荷時や一部のサービスに問題が発生した場合、基幹業務の正常な稼働を確保するため、一部の機能を一時的に停止または縮小することがあります。
    • :たとえば、電子商取引システムのレコメンド サービスに問題がある場合、商品のレコメンドを一時的に提供しないことを選択できますが、他のショッピング機能は引き続き利用できます; ショッピング カート履歴サービスに問題がある場合、このサービスを一時停止することもできます
    • 対象読者: 主にサービス利用者。サービスのダウングレードにより、消費者は特定の機能を使用できなくなる可能性がありますが、他のコア機能には引き続きアクセスできます。
  2. ヒューズ:

    • 目的:呼び出し元の保身 サービスAがサービスBを呼び出すと、サービスBのビジネスロジックがサービスCを呼び出す このとき、サービスCの応答がタイムアウトする サービスBはサービスCに依存しているため、サービスBのタイムアウトはサービスCに依存するC が B のビジネスを直接引き起こす ロジックが待機しており、このときサービス A がサービス B を頻繁に呼び出し続けると、サービス B は大量のリクエストの蓄積によりサービスのダウンタイムを引き起こし、サービス雪崩の問題につながる可能性があります。サービス プロバイダーが継続的にエラーを返したり、応答時間がしきい値を超えたりすると、コンシューマ側のヒューズが「オープン」され、サービスアバランシェ効果を回避するために、サービスに対するさらなるリクエストが阻止されます。
    • : たとえば、支払いサービスが遅延し、複数の応答がタイムアウトした場合、サーキット ブレーカーは、一定期間この支払いサービスに転送しないことを決定できますが、直接エラーを返すか、代替戦略を採用します。
    • 対象となるオブジェクト: サーキット ブレーカーは、サービス プロバイダーが継続的なエラー リクエストに圧倒されないよう保護しますが、同時に消費者も保護して、明らかな失敗したリクエストを待たずに迅速な応答を得ることができます。

要約すると、Dubbo のサービスのダウングレードと融合のメカニズムは、主にシステム全体の健全性を保護し、より良いユーザー エクスペリエンスを提供し、主要なビジネスの継続性を確保することを目的としています。

11.9 サーキットブレーカーのメカニズムとダウングレード戦略

ヒューズのメカニズム: ヒューズの動作メカニズムは、主に閉、開、半開の 3 つの状態を切り替えることです。通常の状況では、ヒューズは閉じられています。呼び出し元がダウンストリーム サービスを異常に呼び出すと、ヒューズは異常インジケータ情報を収集し、ヒューズ条件が満たされるとヒューズが開き、呼び出し元は要求時に直接切れます。サーキット ブレーカーは、障害ロジックをインターセプトしてすぐに実行します。一定の時間が経過すると、サーキット ブレーカーは半開状態に戻ろうとします。このとき、サーキット ブレーカーは、呼び出し側がリクエストをサーバーに送信できるようにします。リクエストがサーバーから通常の応答を取得できる場合は、状態をオフに設定し、そうでない場合は、状態をオンに設定します。
Sentinel ヒューズのダウングレードは、リソースが不安定な状態にある場合に呼び出しリンクでのリソースの呼び出しを制限するため、リクエストはすぐに失敗します。

次のダウングレード戦略: (合格すると、RPC-DUBBO プロジェクトのヒューズと電流制限機能をデモンストレーションできます)

  • 平均応答時間 (DEGRADE_GRADE_RT): N 個のリクエストが 1 秒以内に入力され続け、対応する瞬間の平均応答時間 (第 2 レベル) がしきい値 (カウント、ミリ秒) を超えた場合、次の時間ウィンドウ ( DegradeRule の timeWindow 、 s) では、このメソッドの呼び出しは自動的に中断されます (DegradeException がスローされます)。Sentinel のデフォルト統計の RT 上限は 4900 ミリ秒であり、このしきい値を超えるものはすべて 4900 ミリ秒としてカウントされることに注意してください。この上限を変更する必要がある場合は、構成項目 -Dcsp.sentinel.statistic を開始して構成できます。 .max.rt=xxx。
  • 異常な比率 (DEGRADE_GRADE_EXCEPTION_RATIO): 1 秒あたりのリソース リクエスト >= N (構成可能)、およびスループットに対する 1 秒あたりの例外の合計数の比率がしきい値 (DegradeRule のカウント) を超えると、リソースは劣化状態に入ります。つまり、次の時間枠内 (DegradeRule の timeWindow、秒) で、このメソッドへの呼び出しが自動的に返されます。外れ値比率のしきい値範囲は [0.0, 1.0] で、0% ~ 100% を表します。
  • 例外数 (DEGRADE_GRADE_EXCEPTION_COUNT): 過去 1 分間のリソース内の例外の数がしきい値を超えると、サーキット ブレーカーが実行されます。統計時間ウィンドウは分レベルであるため、timeWindow が 60 秒未満の場合、ヒューズ状態の終了後もヒューズ状態に入る可能性があることに注意してください。

11.10 サービス プロバイダーの電流制限戦略を実装するのは比較的簡単です。Redis を使用して分散型電流制限を実装できますが、消費者側のヒューズとサービスの低下についてはどうですか?

サービス利用者側のヒューズとサービスの低下は、特にサービス プロバイダーの障害や応答の遅延に直面した場合に、利用者がリモート サービスを呼び出す際に、より堅牢で復元力を高めることができるようにするためのものです。以下は、コンシューマ側の回線遮断とサービス低下の一般的な実装です。

  1. 消費者用ヒューズ:

    • 仕組み: Circuit Breaker は、特定のサービスへの呼び出しの結果と応答時間を監視します。失敗した呼び出しの割合が設定されたしきい値を超えるか、応答時間が設定時間を超える場合、ヒューズは「オープン」状態になり、新しい要求はリモート サービスに転送されず、直接エラーまたは代替メッセージを返します。戦略。
    • 実装ツール: Hystrix、Resilience4j など、消費者側のサーキット ブレーカーの実装に役立つ既製のライブラリが多数あります。
    • : サーキット ブレーカーは「半開」状態である必要があります。これは、サービスが復元されたかどうかを検出するために、一定期間後にリモート サービスへの一部のリクエストの再転送を試行するために使用されます。
  2. コンシューマ側のサービスのダウングレード (コンシューマ側で直接コードを記述できるため、より簡単に実行できます) :

    • 仕組み: 場合によっては、サービスの機能が一時的に利用できないこと、または応答時間が長いことを消費者がすでに知っている場合があります。この場合、消費者は、リモート サービスを待つ代わりに、別の代替サービスを呼び出すか、事前設定されたデフォルトにフォールバックするか、簡素化された機能を提供するかを選択できます。
    • 実装ポリシー: サービス低下ポリシーは、コンシューマ コードにハードコーディングすることも、実行時に変更できるように動的ポリシーとして構成することもできます。ダウングレード戦略の選択は通常、ビジネス要件に基づいて行われます。
    • : サービスの低下は一時的な戦略である必要があり、リモート サービスが復元されたら、コンシューマは通常の通話モードに戻る必要があります。
  3. 以下と組み合わせて使用​​します

    • サーキット ブレーカーとサービスのダウングレードは、多くの場合組み合わせて使用​​されます**。たとえば、サーキット ブレーカーがリモート サービスの障害を検出してオープンすると、消費者はサービス ダウングレード戦略を開始し、ユーザー エクスペリエンスを最大化するための代替サービスまたはデフォルト値を提供できます**。

実際の使用では、Dubbo はサーキット ブレークとサービス低下に対するサポートを提供しています。ただし、これらの機能を非 Dubbo 環境に実装したい場合は、Hystrix や Resilience4j などのオープン ソース ライブラリの使用を検討できます。

11.11 Hystrix のヒューズはどのように実装されていますか? 新しい jvm スレッドを開いてサービス呼び出しの概要を保持し、しきい値に従ってダウングレードするか、それとも AOP 通知後を直接使用するかを決定する必要がありますか?

Hystrix のヒューズの実装は比較的複雑で、効率的で遅延の少ない障害分離メカニズムを提供することを目的としています。その主な実装は次のとおりです。

  1. コマンド モード:
    Hystrix は、各リモート呼び出しまたは各依存サービスをコマンド オブジェクトとしてカプセル化します。これらのコマンド オブジェクトは Hystrix の中核であり、実際の操作の実行、実行ステータスの追跡、および失敗条件の処理を担当します。

  2. スレッド プールの分離:
    デフォルトでは、Hystrix はスレッド プールの分離を使用してリソースを保護します。各コマンドは独自のスレッド プールで実行されます。スレッド プールがいっぱいの場合、新しいリクエストはキューに入れられずに拒否され、サービス障害によるシステム リソースの枯渇を防ぎます。

  3. セマフォ分離:
    場合によっては、スレッド プール分離が最良の選択ではない可能性があります (非同期依存呼び出しなど)。現時点では、Java を使用してSemaphore同時実行数を制限するセマフォ分離を使用できます。

  4. ローリング ウィンドウ統計 (Redis のスライディング ウィンドウ電流リミッターと同様) :
    Hystrix は統計のために別のスレッドを開く必要はなく、ローリング ウィンドウを使用して最近の実行情報 (成功、失敗、拒否など) をカウントします。これは、アプリケーションの開始から現在までの状況全体ではなく、過去の期間 (たとえば、最後の 10 秒) の呼び出しをカウントすることを意味します。

  5. ヒューズ ロジック:
    Hystrix のヒューズは、ローリング ウィンドウの統計データに基づいてヒューズを開くかどうかを決定します。たとえば、失敗した通話の割合が設定されたしきい値を超えると、サーキット ブレーカーが開きます。サーキット ブレーカーがオンの場合、すべてのリクエストは実際には実行されずに直接拒否されます。設定されたスリープ時間が経過すると、サーキット ブレーカーは半開状態になり、依存するサービスの正常性をテストするためにプロバイダーに部分的なリクエストを送信できるようになります。

  6. AOP :
    Hystrix の内部実装には多くの詳細が含まれますが、ユーザーにとっては、(AOP を使用して) アノテーションを通じてメソッドを Hystrix コマンドにラップできる簡潔な API が提供されます。これにより、アプリケーションに Hystrix サポートを追加することが非常に簡単になります。

一般に、Hystrix は、リアルタイム統計および融合ロジックを含む統合戦略を使用して、スレッド プールまたはセマフォ分離と組み合わせて融合を実装し、強力で柔軟な障害分離メカニズムを提供します。

11.12 ヒューズ メカニズムは主にサービスの利用者を保護しますよね?

サーキット ブレーカーの主な目的は、システム全体の健全性と可用性を保護することですが、ある意味、サービスの利用者を保護することもあります。具体的には、「保護」とは次のことを意味します。

  1. サービス コンシューマの保護: サービス (ま​​たはその関連依存関係) が遅延や障害を示し始めると、サーキット ブレーカーは、飽和または障害が発生している可能性があるサービスでリクエストを待機させるのではなく、リクエストをすぐに拒否できます。これは、コンシューマーが決して戻ってこない可能性のある応答を待ち続けることがなくなり、より早く失敗し、デフォルト値を返す、別のサービス インスタンスを再試行する、エラー処理ロジックをトリガーするなどの代替戦略にフォールバックできる可能性があることを意味します。

  2. サービス プロバイダーの保護: サーキット ブレーカーは、過負荷になっている可能性があるサービスへのさらなるリクエストを減らし、サービスに回復のための時間とスペースを与えるため、サービス プロバイダーを保護することもできます。また、サーキット ブレーカーは、すでに障害が発生した状態にあるサービスに大量のリクエストが流れるのを防ぐことができるため、障害が発生したサービスによってシステム全体がダウンすることも防ぎます。

  3. カスケード障害の防止: マイクロサービス アーキテクチャでは、多くの場合、1 つのサービスが他の複数のサービスに依存します。これらのサービスのいずれかに障害が発生した場合、適切な保護メカニズムがなければ、この障害はシステム全体に急速に伝播し、広範囲にわたる障害を引き起こす可能性があります。サーキット ブレーカーは、ファスト フェイルとリクエストの拒否によって、この連鎖的な障害の伝播を防ぎます。

要約すると、サーキット ブレーカーはサービスの利用者を保護しますが、より広範な目的はシステム全体の健全性と安定性を確保することです

12 netty はチャネル多重化をどのように実装するか

12.1 Netty のチャネル多重化と HTTP のキープアライブ: 「Netty 多重化チャネルと長い接続の違いは何ですか?」と尋ねることに相当します。

TCP 上での HTTP 多重化と言う場合、通常はKeep-AliveHTTP のメカニズムを意味します。従来の HTTP/1.0 では、デフォルトの動作では、要求/応答のペアが完了するたびに TCP 接続を閉じます。しかし、その後、パフォーマンスを最適化し、接続の確立/切断のオーバーヘッドを削減するために、キープアライブ メカニズムが導入されました。HTTP/1.1 では、キープアライブはデフォルトで有効になっており、複数の HTTP リクエスト/レスポンスのペアを HTTP/1.1 上で完了できます。同じTCP接続です。Netty のChannel多重化とは、アプリケーションのライフサイクル全体を通じて確立された TCP 接続の多重化を指します。Netty は、接続プールを維持することで接続の頻繁な確立と切断を回避し、再利用を実現します。したがって、どちらも本質的にはオーバーヘッドを削減するために TCP 接続を多重化していますが、実装の詳細とコンテキストは異なります。HTTP のキープアライブはプロトコル レベルで最適化されますが、Netty のチャネル多重化には、より多くのフレームワークとアプリケーション層の最適化が含まれます。

HTTP キープアライブと TCP キープアライブの関係:
HTTP キープアライブ メカニズムは通常、TCP 接続に実装されますが、TCP キープアライブ機能には依存しません。これらは異なるプロトコル層で動作し、それぞれが独立して異なる問題を解決します。HTTP のキープアライブは、確立された接続上で複数のリクエストと応答を効率的に送信する方法を考慮しますが、TCP のキープアライブは、アイドル状態の接続がまだ生きているかどうかを検出する方法を考慮します。

12.2. Netty はチャネル多重化をどのように実装するか:

12.2.1 マクロレベル:

  • 接続プール: Netty は接続プールを使用して接続を再利用できます。接続が確立され、現在使用されていない場合は、その接続を接続プールに入れることができます。新しいリクエストが到着して接続が必要になった場合、既存の接続を接続プールから直接取得できるため、接続を再確立するオーバーヘッドが回避されます。

  • EventLoop : Netty には と呼ばれるコアコンポーネントがありEventLoop、新しい接続の受け入れ、データの読み取り/書き込みなどの I/O イベントの処理を担当します。それぞれのEventLoop複数を関連付けることができChannel、これらすべてがChannel同じスレッドを共有します。この設計により、Channel同じサーバー上のすべての I/O 操作が同じスレッドによって順次実行されるため、マルチスレッド同期のオーバーヘッドが回避されます。多くの者が1 つの を共有するChannelため、これも多重化の方法の 1 つですChannelEventLoop

  • ChannelPipeline : Netty 内でデータが流れるとき、データは と呼ばれるプロセス チェーンを通過しますChannelPipelineこの処理チェーンはいくつかの から構成されますChannelHandler1 つをChannel再利用すると、それに関連するものもChannelPipeline再利用できるため、処理チェーンを再構築するオーバーヘッドが軽減されます。

つまり、Netty はさまざまな方法でChannel多重化を実現し、パフォーマンスを最適化し、リソースの使用量を削減します。

12.2.2 マイクロレベル: 接続の再利用を実現するために、なぜ netty は検出リクエストを定期的に送信する必要があり、このリクエストは http プロトコルではなくビジネスに配置されますか?

Netty がChannelマイクロレベルで多重化をどのように実装しているかを調べるときは、接続の健全性を考慮する必要があります。ネットワーク アプリケーションでは、ネットワークの中断、サーバーの再起動、ミドルウェアの介入など、さまざまな理由により接続が不安定になったり、無効になったりすることがあります。

  • ハートビート検出: 接続の状態を確認し、再利用可能であることを確認するために、Netty は通常、ハートビート メカニズムを使用します。ハートビート メカニズムは、長期間データ交換がない接続において、Netty が定期的に小さなデータ パケットを送信して、接続がまだ生きているかどうかを確認することを意味します。これは、無効な接続を適時に検出し、接続プールから削除するのに役立ちます。

  • ハートビートが HTTP プロトコル層ではなくビジネス層で行われる理由:

    • 柔軟性の向上: ビジネス層でハートビート検出を実装することにより、Netty は柔軟性を高めます。開発者は、実際のビジネス ニーズに応じてハートビートの頻度、形式、応答動作などをカスタマイズできます。
    • プロトコル中立: Netty は HTTP プロトコルだけをサポートしません。実際、Netty は複数のプロトコルをサポートするプロトコル中立のネットワーク フレームワークです。ハートビート メカニズムをビジネス層に配置することは、さまざまなプロトコルに統一されたハートビート処理方法を提供できることを意味します。
    • プロトコル レベルのオーバーヘッドを回避する: HTTP プロトコル層でハートビートを実装すると、HTTP ヘッダーの処理、冗長状態の維持などの不必要なオーバーヘッドが発生する可能性があります。シンプルで効率的なハートビート メカニズムをビジネス層に実装できます。
  • 接続の健全性の評価: ハートビートの検出に加えて、Netty は他のメカニズムを使用して接続の健全性を評価することもあります。たとえば、例外、I/O タイムアウト、間違ったデータ形式などの接続を監視します。これらは、異常な接続の兆候である可能性があります。

一般に、Netty がChannel多重化を実装する場合、接続を効果的に管理および多重化する方法を考慮するだけでなく、接続の健全性と安定性を確保することも考慮する必要があります。これには、再利用時に接続の信頼性を維持するために、ハートビート検出、例外監視、タイムアウト処理などのさまざまなメカニズムと戦略が含まれます。

12.3 接続プール: Netty は接続プールを使用して接続を再利用できます。接続が確立され、現在使用されていない場合は、その接続を接続プールに入れることができます。接続が長期間使用されず、接続プールに入れる必要があるのはなぜですか?

接続プールが必要な理由、および未使用の接続が接続プールに入れられる理由を説明する前に、まず接続プールの中核となる目的、つまりリソー​​スの使用効率を向上させ、接続の作成と破棄のオーバーヘッドを削減することを明確にする必要があります。

  1. 接続の作成と破棄のオーバーヘッド: 新しい接続、特に TCP 接続の作成には時間とシステム リソースがかかります。これには、3 ウェイ ハンドシェイクや TCP パラメータのネゴシエーションなどの手順が含まれます。同様に、接続を閉じるには時間がかかり、TIME_WAIT 状態になり、システム リソースが一時的に占有される可能性があります。作成と切断を頻繁に行うと、システム リソースの浪費やパフォーマンスの低下につながります。

  2. 接続を再利用する利点: 毎回新しい接続を作成するのではなく、既存の接続を再利用する方が優れています。このようにして、この接続を直接使用できるため、新しい接続を作成する際の遅延が回避されます。

  3. 長期間使用されていない接続を接続プールに入れる理由:

    • インスタントな可用性: 未使用の接続をプールするということは、それらの接続がまだアクティブであり、接続確立の遅延が発生することなく、すぐに再度使用できることを意味します。
    • リソース管理 (トークン バケットに似ており、自身を保護できます) : 接続の存続を維持するにはリソースが消費されますが、頻繁に接続を作成および破棄することに比べれば、このオーバーヘッドは小さいです。通常、接続プールにはサイズ制限があり、それを超えるとアイドル状態の接続が閉じられ、リソースが無駄になりすぎないようになります。
    • 頻繁な接続の確立/切断を防止する: 一部のアプリケーション シナリオでは、リクエストが突然増加する場合があります。トラフィックが少ないときにアイドル状態の接続をすべて閉じ、トラフィックが多いときに突然大量の新しい接続が必要になると、パフォーマンスのボトルネックが発生します。接続プーリングを使用すると、このようなトラフィックの変化に迅速に対応できるため、この状況を軽減できます。

全体として、接続プールはパフォーマンスとリソースの使用効率を考慮して設計されています。長期間使用されていない接続をプールすると、毎回新しい接続を作成するというオーバーヘッドが発生するのではなく、必要なときに迅速な応答が保証されます。

12.4 接続プールに入れないと接続を維持できないのですか?

実際、接続を接続プールに入れずに維持することは、特に長期にわたる永続的な接続の場合、実行可能な戦略です。ただし、接続プールを使用することにはいくつかの利点と理由があります。

  1. リソース管理: 同時実行性の高いシステムでは、数千または数万の接続が存在する可能性があります。これらの接続がすべて使用されていない場合でも、すべての接続が維持されると、システム リソースがすぐに使い果たされる可能性があります。接続プールは、これらの接続を管理する集中的な場所を提供し、制限を超えた接続が適切に閉じられるようにします。

  2. 接続の再利用: 接続プールは、アイドル状態の接続を保存する場所であるだけでなく、接続の効果的な再利用を保証します。リクエストに接続が必要な場合、接続プールは、新しい接続が確立されるのを待つ代わりに、確立された接続をすぐに提供できます。

  3. パフォーマンスの最適化: 接続プールは、一定数の接続を事前に作成する (予熱) ように構成できるため、トラフィックが突然増加した場合でも、これらの事前に確立された接続をすぐに使用できます。

  4. 接続の健全性チェック: 接続プールには通常、プール内の接続がまだ健全で利用可能であることを定期的にチェックするメカニズムがあります。問題を発見するために実際に必要になるまで待つことなく、問題のある接続を交換または修復できます。

  5. 統合された接続管理: 接続プールは、アプリケーションがすべての接続を管理するための統合された一元的な場所を提供します。これは、接続パラメータ、タイムアウト値、最大/最小接続数などを 1 か所で設定できることを意味します。

システムの同時接続が非常に少なく、それらの接続が永続的で存続期間が長い場合は、接続プールを使用しないのが合理的である可能性があります。ただし、ほとんどの同時実行性と動的システムの場合、接続プーリングは接続を処理するための効率的で管理しやすい方法を提供します。

12.5 TCP ステートレスは誰に対して、また誰に対して?

1 接続であるため、ピア エンドとローカル エンドが存在する必要がありますが、それでもステートレスなのはなぜですか? 2 長期間存在する接続は、ネットワークの中断またはその他の問題が原因で「古くなった」または異常になる可能性があります。ここでは、ネットワークの中断と異常な接続についても言及しましたが、それ自体が状態の説明でもあります。

あなたの質問は非常に理にかなっています。詳しく見てみましょう。

  1. 接続の状態:

    • TCP 接続が「ステートレス」であると言うとき、実際には、アプリケーション層の観点から、この接続の前にどの接続が使用されたかに関係なく、同じソケットからの任意のリクエストによって接続が多重化できることを意味します。ただし、TCP プロトコルの観点から見ると、接続には確立、接続、クローズなどの状態があります。さらに、各接続は一意の 4 つのタプル (送信元 IP、送信元ポート、宛先 IP、宛先ポート) によって識別されます。
    • この「ステートレス」の説明は、接続が接続プールに解放されると、その接続を使用する次のリクエストでは、接続が以前に何をしていたかを知る必要も気にする必要もないことを強調するためのものです。
  2. 接続の健全性とステータス:

    • あなたは、絶対に正しい。実際、接続の「健全性」について話すとき、私たちは実際にはその状態を説明しています。たとえば、ネットワークの停止により中断された接続は「切断」状態になります。
    • 「ステートレス」と言うとき、実際には、同じ TCP ソケットに属するアプリケーション層のリクエストが接続に対して透過的であることを強調したいのですが、これは、下位レベル (TCP 層など) で接続されることを意味するものではありません。状態。実際、TCP プロトコルには、接続のさまざまな状態を処理するための非常に明確なステート マシンがあります。

一般に、「ステートレス」と表現されるのは、接続プール内の接続をアプリケーションの観点から見ているということです。しかし、ネットワーク層とトランスポート層に着目すると、各接続には独自の内部状態があり、これはデータの正しい送信と接続の管理を保証するために重要です。

12.6 接続の多重化: 接続プールは、アイドル状態の接続を保存する場所であるだけでなく、接続の効果的な多重化も保証します。リクエストに接続が必要な場合、接続プールは、新しい接続が確立されるのを待つ代わりに、確立された接続をすぐに提供できます。ここで、コネクションプールが提供するコネクションは、リクエストが属するソケットに対応するコネクションであるはずですよね?

はい、あなたの理解は正しいです。接続プールがすでに確立されている接続を提供できると言うとき、私が言いたいのは、接続プール内の接続は、要求されたターゲット サービスまたはホストと一致する必要があるということです。

明確にしておきます:

  1. クライアントが特定のサーバーと対話する必要がある場合、まず接続プール内にそのサーバーとの間にアイドル接続がすでに確立されているかどうかを確認します。
  2. 存在する場合、クライアントはその接続を接続プールから取り出して使用するため、接続を再確立するオーバーヘッドが回避されます。
  3. 接続プールにターゲット サーバーへの接続がない場合、クライアントは新しい接続を作成する必要があります。

したがって、接続プールによって提供される接続は、リクエストのターゲット サービスまたはホストと一致する必要があります。

おすすめ

転載: blog.csdn.net/yxg520s/article/details/132451105