dubbo LeastActiveLoadBalance 源码

2022-10-20 浏览 (589)

dubbo LeastActiveLoadBalance 代码

文件路径:/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/loadbalance/LeastActiveLoadBalance.java

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.dubbo.rpc.cluster.loadbalance;

import org.apache.dubbo.common.URL;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.RpcStatus;

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

/**
 * LeastActiveLoadBalance
 * <p>
 * Filter the number of invokers with the least number of active calls and count the weights and quantities of these invokers.
 * If there is only one invoker, use the invoker directly;
 * if there are multiple invokers and the weights are not the same, then random according to the total weight;
 * if there are multiple invokers and the same weight, then randomly called.
 */
public class LeastActiveLoadBalance extends AbstractLoadBalance {

    public static final String NAME = "leastactive";

    @Override
    protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
        / Number of invokers
        int length = invokers.size();
        / The least active value of all invokers
        int leastActive = -1;
        / The number of invokers having the same least active value (leastActive)
        int leastCount = 0;
        / The index of invokers having the same least active value (leastActive)
        int[] leastIndexes = new int[length];
        / the weight of every invokers
        int[] weights = new int[length];
        / The sum of the warmup weights of all the least active invokers
        int totalWeight = 0;
        / The weight of the first least active invoker
        int firstWeight = 0;
        / Every least active invoker has the same weight value?
        boolean sameWeight = true;


        / Filter out all the least active invokers
        for (int i = 0; i < length; i++) {
            Invoker<T> invoker = invokers.get(i);
            / Get the active number of the invoker
            int active = RpcStatus.getStatus(invoker.getUrl(), invocation.getMethodName()).getActive();
            / Get the weight of the invoker's configuration. The default value is 100.
            int afterWarmup = getWeight(invoker, invocation);
            / save for later use
            weights[i] = afterWarmup;
            / If it is the first invoker or the active number of the invoker is less than the current least active number
            if (leastActive == -1 || active < leastActive) {
                / Reset the active number of the current invoker to the least active number
                leastActive = active;
                / Reset the number of least active invokers
                leastCount = 1;
                / Put the first least active invoker first in leastIndexes
                leastIndexes[0] = i;
                / Reset totalWeight
                totalWeight = afterWarmup;
                / Record the weight the first least active invoker
                firstWeight = afterWarmup;
                / Each invoke has the same weight (only one invoker here)
                sameWeight = true;
                / If current invoker's active value equals with leaseActive, then accumulating.
            } else if (active == leastActive) {
                / Record the index of the least active invoker in leastIndexes order
                leastIndexes[leastCount++] = i;
                / Accumulate the total weight of the least active invoker
                totalWeight += afterWarmup;
                / If every invoker has the same weight?
                if (sameWeight && afterWarmup != firstWeight) {
                    sameWeight = false;
                }
            }
        }
        / Choose an invoker from all the least active invokers
        if (leastCount == 1) {
            / If we got exactly one invoker having the least active value, return this invoker directly.
            return invokers.get(leastIndexes[0]);
        }
        if (!sameWeight && totalWeight > 0) {
            / If (not every invoker has the same weight & at least one invoker's weight>0), select randomly based on 
            / totalWeight.
            int offsetWeight = ThreadLocalRandom.current().nextInt(totalWeight);
            / Return a invoker based on the random value.
            for (int i = 0; i < leastCount; i++) {
                int leastIndex = leastIndexes[i];
                offsetWeight -= weights[leastIndex];
                if (offsetWeight < 0) {
                    return invokers.get(leastIndex);
                }
            }
        }
        / If all invokers have the same weight value or totalWeight=0, return evenly.
        return invokers.get(leastIndexes[ThreadLocalRandom.current().nextInt(leastCount)]);
    }
}

相关信息

dubbo 源码目录

相关文章

dubbo AbstractLoadBalance 源码

dubbo ConsistentHashLoadBalance 源码

dubbo RandomLoadBalance 源码

dubbo RoundRobinLoadBalance 源码

^