ロードバランシング戦略と原則リボン

ロードバランスロードバランシングは解決できないすべての要求を生成するための機械(プロセス)のアルゴリズムを解決するために使用されます。あなたは負荷分散トラフィックとしてnginxの使用することができ、リボンはクライアントの負荷分散を提供し、ダボサービスのロードバランシングでの通話や使用のロードバランシングに非常に多くの場所。

負荷分散を使用することの利点は明白もたらします:

1つの駅またはダウン複数のサーバのクラスタは、残りのサーバがサービスをし続けることができることを確実にするためにダウンしていないときは
、機械の健全な利用を確保するために複数のマシンを使用していませんピーク時には、システムのCPUの急激な上昇につながるので、
一般的に達成するためのいくつかの戦略があり、ロードバランシングされている:

ランダム(無作為)
世論調査(ラウンドロビン方式)
、一貫したハッシュ(ConsistentHash)
ハッシュ(ハッシュ)
に重み付け(加重)
ILoadBalanceロードバランサ
、それはすべての利用可能なのサーバーリストの取得ILoadBalanceと呼ばれるロードバランサを表し、ユーザ・インターフェース、など追加したサーバー運用、サーバーの動作を選択し、提供内のリボンは、クライアントサービスのロードバランシング機能の提供ですサーバーのリスト、および上そう。:継承ILoadBalanceは、以下





のiRuleルーティングによれば、EurekaClient(EurekaClient実装クラスDiscoveryClient)サービス情報から、ロードバランサ、及びIPingに応じてサービスの可用性を決定します。

ユーレカクライアントそれから、登録情報のための1つを得るために、ロードバランサ、長い時間?BaseLoadBalancerクラスのコンストラクタPingTaskタスクsetupPingTaskを(開き、BaseLoadBalancerコンストラクタ);以下のように、コードは次のとおりです。

    BaseLoadBalancer公開(文字列名、ルールのiRule、LoadBalancerStats統計、
            ピングのiPING、IPingStrategy pingStrategy){
        IF(logger.isDebugEnabled()){
            logger.debug( "ロードバランサ:初期化");
        }
        this.name =名;
        this.ping =ピングの;
        this.pingStrategy = pingStrategy;
        setRule(ルール);
        setupPingTask();
        lbStats =統計;
        INIT();
    }
setupPingTask()は、特定のコードロジックのは、それは、デフォルトは10 pingIntervalSecondsある、ShutdownEnabledTimer PingTaskタスクを実行開きすなわち、10秒ごとに、EurekaClientに「ピング」を送信します。
setupPingTaskボイド(){
        IF(canSkipPing()){
            リターン。
        }
        IF(lbTimer = nullを!){
            LbTimer.cancel();
        }
        lbTimer新しい新ShutdownEnabledTimer =( "NFLoadBalancer-PingTimer-" +名前、
                真の);
        lbTimer.schedule(新新PingTask()、0、pingIntervalSeconds * 1000);
        forceQuickPing ();
    }
PingTask源は、すなわち、新たなオブジェクトがピンガーあり、runPinger()メソッドを実行します。

異なる通知ServerStatusChangeListenerまたはChangeListenersには起こった場合に表示runPingerピンガーの()メソッドは、結果が返された場合、サービスを取得するために、最終的な可用性pingerStrategy.pingServers(ピング、allServers)、前と同じによると、EurekaClientは、登録先のリストを取得できません変更、更新または再プル。

完全なプロセスは以下のとおりです。

初期化中LoadBalancerClientは(RibbonLoadBalancerClientが実装クラスである()メソッドを実行する)、ユーレカ登録センターにサービス登録リストを取得するILoadBalanceを(BaseLoadBalancerが実装クラスである)を通過し、送信「ピング」は、すべての10S EurekaClientにサービスの可用性を決定しますあなたが変更した場合は、サービスとサービスの前に一貫性のない可用性の数や、レジストリの更新や再プルから、開催されました。これらのサービスの登録リストでLoadBalancerClientは、あなたが特定のiRuleに基づいてバランスを読み込むことができます。



iRuleルーティング
のiRuleインタフェースは、ポリシーをロードバランシングを表す:

パブリックインターフェイスのiRule {
    公開サーバ(オブジェクトキー)を選択し、
    公共ボイドsetLoadBalancer(ILoadBalancer LB);
    公共ILoadBalancer getLoadBalancerを();    
}
のiRuleインターフェース実装クラスは以下の通りである:





前記ランダムRandomRuleを表します戦略は、RoundRobinRuleはBestAvailableRuleのような要求ポリシーとの最小数を表し、WeightedResponseTimeRule重み付け戦略を表し、ポーリングポリシーを表します。

ランダムな戦略がランダムサーバーからサーバーを選択するために、シンプルさで、RandomRuleコードは次の通りです:

サーバーを選択して、パブリック(ILoadBalancer LB、オブジェクトキー){
    IF(LB == NULL){
        ヌルリターン;
    }
    サーバサーバ= NULL;

    一方(サーバ== NULL){
        IF(Thread.interrupted()){
            戻りNULL;
        }
        リスト<サーバ> lb.getReachableServers UPLIST =();
        リスト<サーバ> allList = LBをgetAllServers();
        int型serverCount allList.size =();
        IF(serverCount == 0){
            戻りNULL;
        }
        int型のインデックス= rand.nextInt(serverCount); //インデックス値ランダム内部使用JDKランダムクラスインデックス取得
        サーバ= upList.get(インデックス); //サーバーインスタンスを取得

        IF(サーバ== NULL){
            Thread.yieldに();
            続行;
        }

        (server.isAlive()){IF
            リターン(サーバー);
        }

        サーバー= NULL;
        ; Thread.yield()へ
    }
    戻りサーバー;
}
RoundRobinRuleは、すべてのポーリングポリシーが、そのような5台のサーバーの合計として、サーバーを示し除去1取ら第1段階、第二を取るために第2段階、第三段階における第3、など:

    パブリックサーバを選択(ILoadBalancer LB、オブジェクトキー){
        IF(LB == NULL){
            log.warn ( "バランサNOをロード");
            戻りNULL;
        }

        サーバサーバ= NULL;
        INT COUNT = 0;
        一方(サーバCOUNT == NULL && ++ <10){
            リスト<サーバ> reachableServers lb.getReachableServers =();
            リスト<サーバ> allServers = lb.getAllServers()。
            INTアップカウント= reachableServers.size()。
            INT serverCount = allServers.size()。

            IF((アップカウント== 0)||(serverCount == 0)){
                log.warn( "いいえロードバランサから利用可能なサーバーアップ:" + LB)。
                ヌルを返します。
            }

            INT nextServerIndex = incrementAndGetModulo(serverCount)。
            サーバ= allServers.get(nextServerIndex)。

            IF(サーバ== NULL){
                / *一時的に。* /
                Thread.yield();
                継続する;
            }

            IF(server.isAlive()&&(server.isReadyToServe())){
                リターン(サーバー)
            }

            //次。
            サーバー= NULL;
        }

        IF(カウント> = 10){
            log.warn( "ロードバランサから10回の試行の後に利用可能な生きているサーバ:"
                    + LB)。
        }
        サーバーを返します。
    }

    / **
     * {@linkのAtomicInteger#incrementAndGet()}の実装に触発。
     *
     * @paramモジュロカウンタの値をバインドする剰余。
     *次の値@return。
     * /
    プライベートINT incrementAndGetModulo(INTモジュロ){
        (;;){ため
            INT電流= nextServerCyclicCounter.get()。
            次に= INT(現在+ 1)モジュロ%;
            IF(nextServerCyclicCounter.compareAndSet(現在、次))が
                次を返す;
        }
    }
があり、WeightedResponseTimeRuleポーリングが親クラスを使用して、重みリストで開始しない、RoundRobinRuleを継承デフォルトの更新重みリストのタイミングタスクは、スケジュールされたタスクは、応答時間のインスタンスに基づいて再上場重量に更新されます、30秒ごとに、それを行う方法を選択して、(0,1)との二重の乱数を与えるために、最大の重みを乗じてrandomWeightは、その後わずかに、randomWeight添字よりも大きいの最初のインスタンスを検索し、そのインスタンスを返し、コードを重みリストをトラバース。

同時要求の最低額を選択するためのBestAvailableRuleポリシーサーバー:

公共選択してサーバー(オブジェクトキー){
    IF(loadBalancerStats == nullの){
        リターンsuper.choose(キー);
    }
    リスト<サーバ>サーバリスト= getLoadBalancer()getAllServers()。 ; //すべてのサーバーのリストを取得する
    int型minimalConcurrentConnections = Integer.MAX_VALUEのを。
    CURRENTTIME =ロングのSystem.currentTimeMillis();
    サーバー選ば= NULL;
    (サーバサーバ:サーバリスト)のために{//各サーバを介して反復
        ServerStats serverStats = loadBalancerStats.getSingleServerStat(サーバー); //は、 各サーバのステータスを取得する
        (serverStats場合! isCircuitBreakerTripped(CURRENTTIME)){//回路遮断器がトリガされていない場合は継続
            INT concurrentConnections = serverStats.getActiveRequestsCount(CURRENTTIME); //は、 サーバーへの要求の現在の数を取得する
            (concurrentConnections <minimalConcurrentConnections){//各サーバ比較場合は要求間数、および選択された変数サーバ要求の最小数を選択して配置
                minimalConcurrentConnections = concurrentConnectionsと、
                朝鮮=サーバー;
            }
        }
    }
    (== nullのを選択した)場合は{//オプションがない場合には、ロードバランシングのために使用され、すなわちRoundRobinRuleポーリングモード選択ClientConfigEnabledRoundRobinRule、親クラスを呼び出し        
        、戻りsuper.choose(キー);
    }他{
        選ばれたを返します。
    }
}
リボンロードバランシング使用可能な戦略は単に部分を以下、非常に簡単です:

1、RestTemplateは、負荷分散機能のインスタンスを作成するにはしてい

@Bean
@LoadBalanced
RestTemplate RestTemplate(){
    )(新しい新しいRestTemplateを返す;
}
残りのRestTemplate動作時間を用いて、自動的戦略のバランスをロードします、それはRestTemplateで迎撃内LoadBalancerInterceptorに参加します、このインターセプタの役割は、負荷分散を使用することです。
デフォルトのポーリングポリシーを使用しますが、必要であれば、のiRuleを指定して使用される他の戦略は、次のような、達成:

@Bean
公共のiRule ribbonRule(){
    新しい新しいBestAvailableRuleを(返す);
}
このアプローチはまた装うために有効です。

また、実装クラスをロードバランシングを書いて、リボンを参照することができます。

負荷分散ポリシーの以下の方法によって得ることができる、最終的にどのサービスインスタンスを選択した:

        @Autowired
        LoadBalancerClient loadBalancerClient; 
        
        //負荷分散試験が最終的に選択するのどのインスタンス
        パブリックストリングgetChoosedService(){
            ; ServiceInstance ServiceInstance = loadBalancerClient.choose(「USERINFO-SERVICE」)
            のStringBuilder StringBuilderの新しい新しい= SB();
            sb.append( "ホスト:").append(serviceInstance.getHost())追記( "");.
            sb.append( "ポート:").append(serviceInstance.getPort() ).append( "");
            sb.append( "URI").append(serviceInstance.getUri());
            戻りsb.toString();
        }

説明リンク:https://blog.csdn.net/wudiyong22/article/details/80829808

公開された795元の記事 ウォンの賞賛3 ビュー11万+

おすすめ

転載: blog.csdn.net/u010395024/article/details/105043251