blog

リボンの負荷分散 -> ソースコード解析

リクエストがサーバーに到達した後、これらのロードバランサは、特定のアルゴリズムに従って宛先サーバーにリクエストをルーティングするなど、Nginx、F5などのサーバー側の負荷分散、。 クライアント側のロ...

Sep 16, 2020 · 6 min. read
シェア

I. ロードバランシング

ロードバランシングは一般的にサーバーサイドのロードバランシングとクライアントサイドのロードバランシングに分けられます。

  • Nginx、F5などのサーバサイドロードバランサ。リクエストがサーバに到達した後、これらのロードバランサは特定のアルゴリズムに従ってリクエストを宛先サーバにルーティングします。
  • クライアント側の負荷分散とは、前述のRibbonのように、サービス利用者のクライアント側にサーバアドレスのリストを用意し、呼び出し元がリクエストを行う前に一定の負荷分散アルゴリズムを用いてアクセスするサーバを選択し、リクエスト元のクライアント側で負荷分散アルゴリズムを実行するもの。一般的にはマイクロサービスを指します。

リボンのハイレベルな使用法

  • eureka-clientはすでにサービス・コンシューマーに追加されており、Ribbon関連のJarを追加するので、Jar座標を追加する必要はありません。

  • ご利用ください:

@Bean
// Ribbonロードバランシング
@LoadBalanced
public RestTemplate getRestTemplate() {
 return new RestTemplate();
}

リボンの負荷分散戦略

  • Ribbonにはさまざまな組み込みのロードバランシング戦略があり、複雑なバランシングのための内部トップレベル接続はcom.netflix.loadbalancer.IRuleで、次のクラスツリーがあります。
  • ロードバランシングポリシーの変更
#あなたがターゲットにしているデプロイされたマイクロサービスの名前。 これを追加しないと、グローバルな効果がある。
lagou-service-resume:
 ribbon:
 NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule#負荷戦略の調整

リボンクラブハウス ソースコード解析

Ribbon仕事の原則

RibbonはrestTemplateにインターセプターを追加します。

図では、コアアウェアネスがロードバランシングマネージャのLoadBalancerで、IRuleやIPingなどに囲まれています。

  • IRule: インスタンス選択時のロードバランシングポリシーオブジェクトです。
  • IP化:ホップ検出を開始し、サービスの可用性を判断するために使用。
  • ServerListFilter: いくつかのルールに従って、受信するサービスインスタンスのリストをフィルタリングします。
  • ServerListUpdater: サービスリストを更新するための一連の操作を定義します。

負荷分散ソースコード解析

RestTemplateインスタンスに@LoadBalancedアノテーションを追加すると、ロードバランシングが可能になります。

  • @LoadBalanced
  • org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration
  • resttemplate カスタマイザーの挿入
  • カスタマイザーを使って、コレクション内の各 resttemplate オブジェクトにインターセプターを追加します。
  • この文脈では、アノテーションされた RestTemplate オブジェクトには、インターセプター LoadBalancerInterceptor が追加されており、このインターセプターは、その後、負荷処理のためにリクエストをインターセプトするものであることが明らかです。したがって、次のステップではインターセプターである LoadBalancerInterceptor の分析に焦点を当てます。
  • org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient#executeで最終的に実行されます。
  • org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration#springClientFactoryに戻る RibbonClientConfigurationはここで組み立てられます。
  • 脳と手足はRibbonClientConfigurationで組み立てられます。
  • com.netflix.loadbalancer.ZoneAwareLoadBalancer#chooseServer
  • com.netflix.loadbalancer.AbstractServerPredicate#getEligibleServers()
  • com.netflix.loadbalancer.AbstractServerPredicate#incrementAndGetModulo
  • org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient#execute() に戻ります。
  • 次に、load chooseServerが実行されたとき、LoadBalancerにはすでにserverListがありますが、このserverListはいつLoadBalancerに注入されるのか、その仕組みは?RibbonClientConfigurationにアクセスしてください。
  • com.netflix.loadbalancer.DynamicServerListLoadBalancer#restOfInitで常にスーパータップします。
  • enableAndInitLearnNewServersFeature() を入力することで、com.netflix.loadbalancer.DynamicServerListLoadBalancer#updateAllServerList も CAS になり、同時実行を制御できます。
  • start()

RoundRobinRuleポーリング戦略のソースコード解析

  • com.netflix.loadbalancer.RoundRobinRule#choose
// ロードバランシング戦略クラスのコアメソッド
public Server choose(ILoadBalancer lb, Object key) {
 if (lb == null) {
 log.warn("no load balancer");
 return null;
 }
 Server server = null;
 int count = 0;
 while (server == null && count++ < 10) {
 // すべての利用可能なサービスインスタンスのリスト
 List<Server> reachableServers = lb.getReachableServers();
 // すべてのサービスインスタンスのリスト
 List<Server> allServers = lb.getAllServers();
 int upCount = reachableServers.size();
 int serverCount = allServers.size();
 if ((upCount == 0) 
 (serverCount == 0)) {
 log.warn("No up servers available from load balancer: " + lb);
 return null;
 }
 // ポーリングインデックスを取得するCAS)
 int nextServerIndex = incrementAndGetModulo(serverCount);
 // インデックスによると、サービスインスタンスオブジェクトを取り出す
 server = allServers.get(nextServerIndex);
 if (server == null) {
 /* Transient. */
 Thread.yield();
 continue;
 }
 if (server.isAlive() && (server.isReadyToServe())) {
 return (server);
 }
 // Next.
 server = null;
 }
 if (count >= 10) {
 log.warn("No available alive servers after 10 tries from load balancer: "
 + lb);
 }
 return server;
 }

RandomRuleランダム戦略ソースコード解析

com.netflix.loadbalancer.RandomRuleに来た、ラウンドトレーニングと同じではありません10回例外をスローするためにループされていない、無限ループを取るように、コアランダムメソッドは、次のようにスレッド乱数です:

Read next

ビットのベストプラクティス - セクション1:ビットサーバーのプライベートサービスを立ち上げる

実際、bit.devはhttpとsshプロトコルをサポートするコンポーネントをエクスポート&インポートする便利な方法と、プレビューや検索が可能な包括的なコンポーネントマーケットプレイスを公式に提供しています。 しかし、bit.devの完全なソリューションを使いたいチームは、そのためにお金を払う必要があり、多くの場合、内部コードの多くは、オープンなbit.devに入れるには適していません。 そのため、プライベートな...

Sep 16, 2020 · 3 min read