03-マイクロサービス-リボン負荷分散

リボンの負荷分散

1.1. 負荷分散の原理

Spring Cloud の最下層では、実際にはリボンと呼ばれるコンポーネントを使用して負荷分散機能を実装しています。

画像-20210713224517686

では、送信したリクエストは明らかに http://userservice/user/1 でしたが、なぜ http://localhost:8081 になったのでしょうか?

1.2. ソースコードの追跡

なぜサービス名を入力するだけでアクセスできるのでしょうか?また、事前に IP とポートを取得する必要があります。

どうやら誰かがサービス名に基づいてサービス インスタンスの IP とポートを取得するのを手伝ってくれたようです。つまりLoadBalancerInterceptor、このクラスは RestTemplate リクエストをインターセプトし、サービス ID に基づいて Eureka からサービス リストを取得し、負荷分散アルゴリズムを使用して実際のサービス アドレス情報を取得し、サービス ID を置き換えます。

私たちはソースコードの追跡を実施します。

1)ロードバランサーインターセポート

1525620483637

ここでの intercept メソッドがユーザーの HttpRequest リクエストをインターセプトし、いくつかのことを実行することがわかります。

  • request.getURI(): リクエスト URI を取得します。この場合は http://user-service/user/8
  • originalUri.getHost(): URI パスのホスト名を取得します。これは実際にはサービス ID です。user-service
  • this.loadBalancer.execute(): サービス ID とユーザー リクエストを処理します。

タイプは次のとおりthis.loadBalancerです。引き続きフォローしてみましょう。LoadBalancerClient

2)ロードバランサークライアント

引き続き実行メソッドに従います。

1525620787090

コードは次のようなものです:

  • getLoadBalancer(serviceId): サービス ID に基づいて ILoadBalancer を取得します。ILoadBalancer はサービス ID を取得して eureka からサービス リストを取得し、保存します。
  • getServer(loadBalancer): 組み込みの負荷分散アルゴリズムを使用して、サービス リストから 1 つを選択します。この例では、ポート 8082 のサービスが取得されていることがわかります。

解放された後、再度アクセスして追跡したところ、8081 を取得していることがわかりました。

外部リンク画像の転送に失敗しました。ソース サイトにはリーチ防止メカニズムが備わっている可能性があります。画像を保存して直接アップロードすることをお勧めします。

案の定、負荷分散は達成されました。

3) 負荷分散戦略 IRule

getServer先ほどのコードでは、サービスの取得で負荷分散を実行するメソッドが使用されていることがわかります。

1525620835911

引き続きフォローアップしてみましょう:

1544361421671

ソース コードのchooseServer メソッドをトレースし続けると、次のコードが見つかりました。

1525622652849

このルールが誰であるかを見てみましょう:

1525622699666

ここでのルールのデフォルト値は one ですRoundRobinRule。クラスの紹介を参照してください。

1525622754316

これが投票の意味ではないでしょうか?

この時点で、負荷分散プロセス全体を明確に理解できました。

4) まとめ

SpringCloudRibbon の最下層はインターセプターを使用して、RestTemplate によって送信されたリクエストをインターセプトし、アドレスを変更します。画像でまとめてみましょう:

画像-20210713224724673

基本的なプロセスは次のとおりです。

  • RestTemplate リクエストをインターセプト http://userservice/user/1
  • ibbonLoadBalancerClient は、リクエスト URL からサービス名を取得します。これは user-service です。
  • DynamicServerListLoadBalancer は、ユーザー サービスに基づいて eureka からサービス リストを取得します
  • eureka はリスト、localhost:8081、localhost:8082 を返します。
  • IRule は組み込みの負荷分散ルールを利用し、リストから 1 つ (localhost:8081 など) を選択します。
  • ibbonLoadBalancerClient はリクエスト アドレスを変更し、userservice を localhost:8081 に置き換え、http://localhost:8081/user/1 を取得して、実際のリクエストを開始します。

1.3. 負荷分散戦略

1.3.1. 負荷分散戦略

負荷分散ルールは IRule インターフェイスで定義され、IRule にはさまざまな実装クラスがあります。

画像-20210713225653000

さまざまなルールの意味は次のとおりです。

組み込みの負荷分散ルールクラス ルールの説明
ラウンドロビンルール サービス リストをポーリングしてサーバーを選択するだけです。これは、リボンのデフォルトの負荷分散ルールです。
可用性フィルタリングルール 次の 2 種類のサーバーは無視してください。 (1) デフォルトでは、このサーバーが 3 回接続に失敗すると、このサーバーは「短絡」状態に設定されます。短絡状態は 30 秒間続きますが、再度接続に失敗すると、短絡時間は幾何級数的に増加します。(2) 同時実行性が高すぎるサーバー。サーバーへの同時接続の数が多すぎる場合、AvailabilityFilteringRule ルールが設定されているクライアントもそれを無視します。同時接続数の上限は、クライアントの ..ActiveConnectionsLimit プロパティによって構成できます。
WeightedResponseTimeRule 各サーバーに重み値を与えます。サーバーの応答時間が長いほど、サーバーの重みは小さくなります。このルールはサーバーをランダムに選択し、この重み値はサーバーの選択に影響します。
ゾーン回避ルール サーバーの選択は、その地域で利用可能なサーバーに基づいて行われます。ゾーンを使用してサーバーを分類します。このゾーンは、コンピューター室、ラックなどとして理解できます。次に、ゾーン内の複数のサービスをポーリングします。
BestAvailableルール ショートサーキットしているサーバーを無視し、同時実行数が低いサーバーを選択します。
ランダムルール 利用可能なサーバーをランダムに選択します。
再試行ルール リトライ機構の選択ロジック

デフォルトの実装は、ポーリング スキームである ZoneAvoidanceRule です。

1.3.2. カスタマイズされた負荷分散戦略

負荷分散ルールは、次の 2 つの方法で IRule 実装を定義することで変更できます。

  1. コード メソッド: order-service の OrderApplication クラスで、新しい IRule を定義します。
@Bean
public IRule randomRule(){
    
    
    return new RandomRule();
}
  1. 構成ファイルによる方法: order-service の application.yml ファイルで、新しい構成を追加すると、ルールを変更することもできます。
userservice: # 给某个微服务配置负载均衡规则,这里是userservice服务
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则 

通常、デフォルトの負荷分散ルールは変更せずに使用されることに注意してください。

1.4.ハングリーロード

リボンはデフォルトで遅延読み込みを使用します。つまり、LoadBalanceClient は最初のアクセスまで作成されず、要求時間は非常に長くなります。

プロジェクトの開始時にハングリー ローディングが作成され、最初のアクセス時間が短縮されます。次の構成を通じてハングリー ローディングを有効にします。

ribbon:
  eager-load:
    enabled: true
    clients: userservice

Dark Horse Programmer から編集された研究ノート

おすすめ

転載: blog.csdn.net/weixin_57486248/article/details/135368360