リボンについてはこの記事で十分です

今日は、マイクロサービスの非常に重要なコンポーネントであるリボンについて見ていきます。分散ネットワークではロードバランサーとして非常に重要な役割を果たします。リボンを紹介する前に、負荷分散という比較的縁遠い用語について話さなければなりません。なぜリモートなのかというと、インタビューで最も話題になっているのは、システムのパフォーマンスを向上させ、高い同時実行性をサポートするためのメッセージキューとキャッシュであり、ロードバランシングについて質問する人はほとんどいないからです。コンポーネントのバランス調整は一般的です。これはすべて運用および保守チームまたはアーキテクトによって行われ、開発者がそれに接触することはほとんどありません。しかし、それは問題ではありません。私たちは CRUD だけでなく、アーキテクチャ上の考え方も持っています。

ロードバランシングとは、簡単に言うと、ネットワークトラフィック(負荷)を異なるネットワークサーバーに分散(均等分散でも不均等分散でも可)することで、サービスの水平水平展開を実現するシステムです。では、負荷分散コンポーネントを設計するように頼まれた場合、どのように設計しますか? 次の要素を考慮する必要があります。

  • サーバーリストを取得して同期するにはどうすればよいですか? レジストリとの対話が含まれます。
  • どうやって負荷を分散するのか?アロケーション戦略に携わる。
  • クライアントリクエストをインターセプトして、転送するサーバーを選択するにはどうすればよいですか? リクエストの傍受に関与します。

これらの質問を念頭に置いて、ロード バランシング + リボン アーキテクチャの原理からロード バランサを設計する方法を学びましょう。これは、いくつかのインスピレーションをもたらすと思います。

1. 負荷分散

1.1 コンセプト

写真

負荷分散の 2 つの基本ポイント:

  • クライアント要求を処理するためにどのサーバーを選択するか。
  • クライアントリクエストを転送します。

基本原則: ハードウェアまたはソフトウェアを通じてサービス リストのリストを維持する。ユーザーがリクエストを送信すると、リクエストはロードバランサーに送信され、ロードバランシングアルゴリズムに従って利用可能なサービスリストからサーバーのアドレスが選択され、リクエストが転送されてロード機能が完了します。 。

1.2 負荷分散の特徴

ロードバランシングの特徴

  • 高パフォーマンス: トラフィックは、さまざまな割り当てルールに従って自動的に割り当てられます。
  • スケーラビリティ: クラスタ内のデバイスまたはリンクの数を簡単に増やすことができます。
  • 高い信頼性: システム内の特定のデバイスやリンクに障害が発生しても、サービスが中断されることはありません。
  • 簡単な構成可能性: 構成とメンテナンスが簡単。
  • 透明性: ユーザーは負荷分散の実行方法を認識せず、負荷分散について気にする必要がありません。

1.3 負荷分散の分類

負荷分散技術はソフトウェアまたはハードウェアに従って分類でき、また、サーバーリストが保存される場所に従ってサーバー側の負荷分散とクライアント側の負荷分散に分類できます。

写真

1.3.1 ハードウェア負荷分散

F5 は、一般的なハードウェア負荷分散製品です。

  • 利点: アプリケーション切り替え、セッション切り替え、状態監視など、ソフトウェア負荷分散にはない多くの機能を備え、パフォーマンスが安定しています。
  • 短所: 機器が高価で、構成が冗長であり、ソフトウェアの負荷分散ほど柔軟ではないため、カスタマイズ要件を満たすことができません。

1.3.2 ソフトウェア負荷分散

Nginx: 優れたパフォーマンス、1W 以上の負荷が可能。ネットワークの 7 番目の層で動作し、HTTP アプリケーションに対していくつかのシャント戦略を実行できます。Nginx は、静的 Web ページおよび画像サーバーとしても使用できます。Nginx は、HTTP、HTTPS、および電子メール プロトコルのみをサポートできます。

LVS(Linux Virtual Server):IPアドレス分散技術とコンテンツリクエスト分散技術を利用して負荷分散を実現する仮想サーバークラスタシステムです。これは、ハードウェア デバイスのネットワーク スループットと接続負荷容量に近い値です。耐荷重性が高く、ネットワーク層 4 で動作し、配信のみに使用されます。LVS+Keepalived などの完全なデュアルシステム ホット バックアップ ソリューションを備えています。ソフトウェア自体は正規表現処理をサポートしておらず、動的と静的な分離を行うことはできません。

1.3.3 サーバーの負荷分散

Nginx と F5 はどちらもサーバー側の負荷分散に分割でき、バックエンド サーバーのアドレス リストはバックエンド サーバーに保存されるか、専用の Nginx サーバーまたは F5 に保存されます。サーバーのアドレス リストのソースは、登録センターを通じて、または手動構成を通じて提供されます。

1.3.4 クライアントの負荷分散

最後に、リボンが登場する番です。リボンはクライアント ロード バランサーに属しており、クライアントは独自にサーバー アドレス リストを維持します。このメンテナンス作業は、Ribbon によって行われます。リボンは、Eureka Server からサービス情報のリストを読み取り、リボンに保存します。サーバーがダウンしている場合、リボンはダウンしているサーバー情報をリストから削除します。リボンにはさまざまな負荷分散アルゴリズムがあり、指定したサーバーにリクエストする独自のルールを設定できます。

2. バランス戦略

上ではさまざまなロード バランシングの分類を紹介しましたが、次に、これらのロード バランサがロード バランシング戦略を使用して、クライアントのリクエストを処理するサーバーを選択する方法を見てみましょう。一般的なバランス戦略は次のとおりです。

2.1 ラウンドロビン

原則: サーバーに 0 から N までの番号が付けられている場合、ラウンドロビン分散戦略により、このリクエストを処理するサーバーとして 0 から順にサーバーが選択されます。

シナリオ: すべての父親が同じソフトウェアおよびハードウェア構成を持つことが適しており、要求頻度は比較的バランスが取れています。

2.2 加重ラウンドロビン

原則: サーバーのさまざまな処理能力に応じて、サーバーにさまざまな重みを割り当てます。その後、リクエストは重みに従ってさまざまなサーバーに割り当てられます。

シナリオ: サーバーのパフォーマンスが異なり、高性能サーバーを最大限に活用し、低パフォーマンスのサーバーに配慮します。

2.3 ランダム平衡(ランダム)

原則: リクエストを異なるサーバーにランダムに割り当てます。

シナリオ: クライアント要求の頻度が比較的ランダムであるシナリオに適しています。

2.4 応答速度バランス(応答時間)

原則: 負荷分散デバイスは各サーバーにプローブ リクエストを送信し、どのサーバーがより速く応答するかを確認します。

シナリオ: サーバーの応答パフォーマンスが常に変化するシナリオに適しています。

注: 応答速度は負荷分散デバイスとサーバー間の速度です。

3. リボンコアコンポーネント

次はハイライトです。Spring Cloud の負荷分散コンポーネントであるリボンを見てみましょう。リボンには主に、ServerList、Rule、Ping、ServerListFilter、ServerListUpdater の 5 つの機能コンポーネントがあります。

写真

3.1 ロードバランサ ロードバランサ

負荷分散を管理するためのコンポーネント。これは、初期化中に YMAL 設定ファイルをロードすることによって作成されます。

3.2 サービスリスト ServerList

ServerList は主に、すべてのサービスのアドレス情報を取得し、ローカルに保存するために使用されます。サービス情報を取得するさまざまな方法に従って、サービス情報は静的ストレージと動的ストレージに分けられます。

  • 静的ストレージ: 構成ファイルからサービス ノード リストを取得し、ローカルに保存します。
  • 動的ストレージ: 登録センターからサービス ノード リストを取得し、ローカルに保存します。

3.3 サービスリストのフィルタリング ServerListFilter

取得したサービス一覧をフィルタリングルールに従ってフィルタリングします。

  • Eureka のパーティション ルールを通じてサービス インスタンスをフィルタリングします。
  • 通信障害の数とサービス インスタンスの同時接続の数を比較して、異常なインスタンスを排除します。
  • サービス インスタンスが属するリージョンに基づいて、同じリージョン内のサービス インスタンスをフィルターで除外します。

3.4 サービスリスト更新 ServerListUpdater

サービス リストの更新とは、リボンがレジストリ センターから最新のレジストリ情報を取得することを意味します。これは、ServerListUpdater インターフェイスによって定義される更新操作です。そして、2 つの実装クラス、つまり 2 つの更新メソッドがあります。

  • スケジュールされたタスクによって更新します。これは、この実装クラス PollingServerListUpdater によって行われます。
  • Eurekaのイベントリスナーを利用して更新します。これは、この実装クラス EurekaNotificationServerListUpdater によって行われます。

3.5 ハートビート検出 Ping

IPing インターフェイス クラスは、利用可能なサービスを検出するために使用されます。利用できない場合は、これらのサービスを削除します。実装クラスには主に、PingUrl、PingConstant、NoOpPing、DummyPing、NIWSDiscoveryPing が含まれます。ハートビート検出戦略オブジェクト IPingStrategy の場合、デフォルトの実装はポーリング検出です。

3.6 負荷分散ポリシールール

リボンの負荷分散戦略は、前述の負荷分散戦略と部分的に同じです。まず、リボンのソース コード内の分散戦略の UML クラス図を見てみましょう。

写真

図からわかるように、主に次のバランス戦略があります。

  • 線形ラウンドロビン バランシング (RoundRobinRule) : 異なるサーバーを順番にリクエストします。利点は、現在のすべての接続のステータスを記録する必要がなく、状態のスケジューリングがないことです。
  • 利用可能なサービスのフィルタリング負荷分散 (AvailabilityFilteringRule) : 複数のアクセス障害によりサーキット ブレーカー状態にあるサービス、および同時接続数がしきい値を超えているサービスをフィルタし、ポーリング戦略に従って残りのサービス リストにアクセスします。デフォルトでは、最後の 3 つの接続が失敗した場合、サービス インスタンスは壊れているとみなされます。その後、30 秒間維持し、回線のクローズ状態に入ります。この時点でも接続に失敗した場合、クローズ状態に入るまでの待ち時間は、失敗の数の増加に応じて指数関数的に増加します。
  • 加重応答時間負荷分散 (WeightedResponseTimeRule) : 応答時間に応じて各サービスに自動的に重みを割り当てます。応答時間が長いほど重みが低くなり、選択される確率が低くなります。
  • ゾーン対応ロード バランシング (ZoneAvoidanceRule) : 呼び出しサービスが配置されているホスティング エリア内のサービスを選択する傾向が高く、待ち時間が短縮され、コストが節約されます。Spring Cloud リボンのデフォルトの戦略。
  • 負荷分散の再試行 (RetryRule) : ラウンドロビン分散戦略を通じてサーバーを選択します。リクエストが失敗するか、応答がタイムアウトになった場合は、現在のサービス ノードを再試行するか、他のノードを選択するかを選択できます。
  • 高可用性バランス (BestAvailableRule) : リクエストに失敗したサーバーを無視し、同時実行性の低いサーバーを見つけようとします。注: これにより、サーバー クラスターへの負荷が 2 倍になります。
  • ランダム負荷分散 (RandomRule) : サーバーをランダムに選択します。これは、同時実行性が比較的大きいシナリオに適しています。

4. リボンインターセプトリクエストの原理

この記事では、最初に「ロード バランサーはどのようにクライアント要求をインターセプトし、転送するサーバーを選択するのか?」という疑問を提起しました。上で紹介したリボン コア コンポーネントと組み合わせると、リボン インターセプト リクエストの原理を整理するための概略図を描くことができます。

写真

  • ステップ 1: リボンは、@loadBalance アノテーションが付けられたすべての RestTemplate をインターセプトします。RestTemplate は HTTP リクエストの送信に使用されます。
  • ステップ 2: リボンのデフォルト インターセプタである LoadBalancerInterceptor を RestTemplate の実行ロジックに追加します。RestTemplate が HTTP リクエストを送信するたびに、そのリクエストはリボンによってインターセプトされます。
  • ステップ 3: インターセプト後、リボンは ILoadBalancer のインスタンスを作成します。
  • ステップ 4: ILoadBalancer インスタンスは、RibbonClientConfiguration を使用して自動構成を完了します。IRule、IPing、ServerList を設定します。
  • ステップ 5: リボンはサービス リストからサービスを選択し、リクエストをこのサービスに転送します。

5. リボン初期化の原理

リボンのソース コードを分析するときは、画期的な解決策を見つける必要があります。@LoadBalanced アノテーションがより適切なエントリです。まず、リボンの初期化のフローチャートを示します。

写真

注釈を追加するコードは次のとおりです。

@LoadBalanced
@Bean
public RestTemplate getRestTemplate() {
   return new RestTemplate();
}
  • ステップ 1: リボンには自動構成クラス LoadBalancerAutoConfiguration があり、SpringBoot が自動構成クラスをロードすると、リボンが初期化されます。
  • ステップ 2: RestTemplate または AsyncRestTemplate に注釈を追加すると、リボンは初期化中に @LoadBalanced の注釈が付けられた RestTemplate と AsyncRestTemplate を収集し、リストに入れます。
  • ステップ 3: 次に、リボンの RestTemplateCustomizer が各 RestTemplate をカスタマイズします。つまり、インターセプター LoadBalancerInterceptor を追加します。
  • ステップ 4: Eureka レジストリからサービス リストを取得し、リボンに保存します。
  • ステップ 5: YMAL 構成ファイルをロードし、負荷分散構成を構成し、ILoadbalancer インスタンスを作成します。

6. リボン同期サービス リストの原則

リボンは、初めて Eureka から完全なレジストリを取得した後、定期的にレジストリを取得します。概略図は次のとおりです。

写真

リボンのコア コンポーネントである ServerListUpdater がレジストリの同期に使用されることは前述しましたが、これにはタイミング同期に特に使用される実装クラス PollingServerListUpdater があります。デフォルトでは、Runnable スレッドは 1 秒後に実行され、その後、Runnable スレッドは 30 秒ごとに実行されます。この Runnable スレッドは、Eureka レジストリを取得するためのものです。

7. エウレカの心拍検出原理

Eureka レジストリはハートビート検出メカニズムを使用してサービスが利用可能かどうかを判断していることがわかっていますが、利用できない場合はサービスが削除される可能性があります。なぜそれが可能なのでしょうか? エウレカには自己保護機構が備わっているため、自己保護機構の閾値に達した場合、将来的に自動的に削除されることはありません。ここでは、Eureka の自己保護メカニズムとサービス削除メカニズムを確認します。

  • Eureka ハートビート メカニズム: 各サービスは 30 秒ごとにハートビートを Eureka Server に自動的に送信し、Eureka Server はこのサービスの最後のハートビート時間を更新します。ハートビートが 180 秒以内に受信されない場合 (バージョン 1.7.2)、タスク サービスに障害があります。
  • Eureka 自己保護メカニズム: 過去 1 分間の実際のハートビート数が予想されるハートビート数よりも小さい場合、自己保護メカニズムがトリガーされ、インスタンスは削除されません。予想されるハートビート数: サービス インスタンスの数 * 2 * 0.85。
  • Eureka サービス削除メカニズム: サービス インスタンスを一度に削除するのではなく、毎回最大 15% がランダムに削除されます。取り外しが完了していない場合は、1分後に取り外してください。

Eureka のハートビート メカニズムとサービス削除メカニズムについて説明した後、Ribbon のハートビート メカニズムを見てみましょう。

8. リボン心拍検出の原理

リボンのハートビート検出原理はエウレカとは異なり、各サービスからリボンにハートビートを送信したり、リボンから各サービスにハートビートを送信することでサービスの生存を検出するわけではありません。まずは写真を撮って、リボンのハートビート検出メカニズムを見てみましょう。

写真

リボン ハートビート検出の原理: ローカルにキャッシュされたサーバー リストを調べて、各サービスのステータスが UP であるかどうかを確認します。特定のコードは isAlive メソッドです。

コアコード:

isAlive = status.equals(InstanceStatus.UP);

それで、どれくらいの頻度で検査されるのでしょうか?デフォルトでは、次の PingTask スケジュール タスクが 30 秒ごとに実行され、ステータスを確認するためにサービスごとに isAlive メソッドが実行されます。 

9. リボン共通設定項目

9.1 エウレカを無効にする

# 禁用 Eureka
ribbon.eureka.enabled=false

サービス登録リストはデフォルトでエウレカから取得されますが、エウレカを使用したくない場合は無効にすることができます。次に、サービスのリストを手動で構成する必要があります。

9.2 サービスリストの設定

ribbon-config-passjava.ribbon.listOfServers=localhost:8081,localhost:8083

この設定は特定のサービス用であり、プレフィックスはサービス名です。設定後は、以前と同様にサービス名を使用してインターフェイスを呼び出すことができます。

9.3 その他の設定項目

写真

10. まとめ

この記事では、Spring Cloud マイクロサービスの負荷分散コンポーネントのリボン アーキテクチャ原理について詳しく説明します。これはいくつかの主要な部分に分かれています。

  • リボンの 6 つのコア コンポーネント
  • リボンがリクエストをインターセプトして転送する方法
  • リボンの初期化の原理
  • リボンが Eureka レジストリを同期する原理
  • EurekaとRibbonのハートビート検出の原理
  • リボンの共通設定項目

おすすめ

転載: blog.csdn.net/qq_28165595/article/details/132007693