dubbo负载均衡源码解析balance

来源:互联网 发布:淘宝客服人工服务时间 编辑:程序博客网 时间:2024/05/29 18:41
Invoker方法进来后会执行AbstractClusterInvoker的doSelect方法。

Invoker<T> invoker = doselect(loadbalance, invocation, invokers, selected);

    private Invoker<T> doselect(LoadBalance loadbalance, Invocation invocation, List<Invoker<T>> invokers, List<Invoker<T>> selected) throws RpcException {        if (invokers == null || invokers.size() == 0)            return null;        if (invokers.size() == 1)            return invokers.get(0);        // 如果只有两个invoker,退化成轮循        if (invokers.size() == 2 && selected != null && selected.size() > 0) {            return selected.get(0) == invokers.get(0) ? invokers.get(1) : invokers.get(0);        }        Invoker<T> invoker = loadbalance.select(invokers, getUrl(), invocation);

最后一句执行的是AbstractLoadBalance的select方法,如下:

    public <T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) {        if (invokers == null || invokers.size() == 0)            return null;        if (invokers.size() == 1)            return invokers.get(0);        return doSelect(invokers, url, invocation);    }

因为默认使用的是RandomLoadBalance,所以我们没有配置dubbo负载均衡策略的情况下,进入的是RandomLoadBalance的doSelect方法。

    protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {        int length = invokers.size(); // 总个数        int totalWeight = 0; // 总权重        boolean sameWeight = true; // 权重是否都一样        for (int i = 0; i < length; i++) {            int weight = getWeight(invokers.get(i), invocation);            totalWeight += weight; // 累计总权重            if (sameWeight && i > 0                    && weight != getWeight(invokers.get(i - 1), invocation)) {                sameWeight = false; // 计算所有权重是否一样            }        }        if (totalWeight > 0 && ! sameWeight) {            // 如果权重不相同且权重大于0则按总权重数随机            int offset = random.nextInt(totalWeight);            // 并确定随机值落在哪个片断上            for (int i = 0; i < length; i++) {                offset -= getWeight(invokers.get(i), invocation);                if (offset < 0) {                    return invokers.get(i);                }            }        }        // 如果权重相同或权重为0则均等随机        return invokers.get(random.nextInt(length));    }


原创粉丝点击