dubbo

dubbo集群容错模式

  1. Failover Cluster:失败重试
  2. Failover Cluster:快速失败
  3. Failsafe Cluster:失败安全
  4. Failback Cluster:失败自动恢复
  5. Forking Cluster:并行调用
  6. Broadcast Cluster:广播调用

dubbo负载均衡策略

  1. Random LoadBalance:随机策略
  2. RoundRobin LoadBalance:轮询策略
  3. LeastActive LoadBalance:最少活跃调用数
  4. ConsisentHash LoadBalance:一致性Hash策略

差异:

  1. 随机策略完全是随机
  2. 轮询策略优点是实现简单,易水平扩展,且比较均衡分发到所有实例,缺点无法知道所有的实例的情况
  3. 最少活跃调用策略考虑了服务器处理能力的不同
  4. 一致性Hash策略设置了虚拟节点,能使分配更均匀
    轮询策略:
public class RoundRobinLoadBalance extends AbstractLoadBalance {

    public static final String NAME = "roundrobin";

    // 记录所有提供服务的数据,<serviceKey+methodName, 调用次数>
    private final ConcurrentMap<String, AtomicPositiveInteger> sequences = new ConcurrentHashMap<String, AtomicPositiveInteger>();

    @Override
    protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
        String key = invokers.get(0).getUrl().getServiceKey() + "." + invocation.getMethodName();
        // 被调用实例数
        int length = invokers.size(); // Number of invokers
        // 最大权重值
        int maxWeight = 0; // The maximum weight
        // 最小权重值
        int minWeight = Integer.MAX_VALUE; // The minimum weight
        // 记录每个实例以及对应的权重
        final LinkedHashMap<Invoker<T>, IntegerWrapper> invokerToWeightMap = new LinkedHashMap<Invoker<T>, IntegerWrapper>();
        // 权重之和
        int weightSum = 0;
        // 遍历所有被调用实例
        for (int i = 0; i < length; i++) {
            // 获取对应实例的权重值
            int weight = getWeight(invokers.get(i), invocation);
            // 设置最大、最小权重值
            maxWeight = Math.max(maxWeight, weight); // Choose the maximum weight
            minWeight = Math.min(minWeight, weight); // Choose the minimum weight
            if (weight > 0) {
                // 只添加有权重的实例
                invokerToWeightMap.put(invokers.get(i), new IntegerWrapper(weight));
                weightSum += weight;
            }
        }

        // 获取该服务的调用次数
        AtomicPositiveInteger sequence = sequences.get(key);
        if (sequence == null) {
            // 没有调用记录则添加数据
            sequences.putIfAbsent(key, new AtomicPositiveInteger());
            sequence = sequences.get(key);
        }

        // 调用次数加一
        int currentSequence = sequence.getAndIncrement();

        // 实例有权重,则根据权重大小分配
        if (maxWeight > 0 && minWeight < maxWeight) {
            // 将调用次数 % 权重总数,得出偏移量 mod
            int mod = currentSequence % weightSum;
            // 遍历最大的权重值,
            // 为什么会遍历它?
            // 因为每一次循环就遍历所有的实例,一个实例最大的权重为 maxWeight,
            // 最多遍历 maxWeight 次所有实例就可以找到想要的实例
            for (int i = 0; i < maxWeight; i++) {
                // 遍历所有的实例
                for (Map.Entry<Invoker<T>, IntegerWrapper> each : invokerToWeightMap.entrySet()) {
                    final Invoker<T> k = each.getKey();
                    final IntegerWrapper v = each.getValue();
                    if (mod == 0 && v.getValue() > 0) {
                        // mod 为 0 表示选中了,但要满足该实例的权重大于 0
                        return k;
                    }
                    if (v.getValue() > 0) {
                        // 实例没选中,则权重减 1,相当于选中机会少了
                        v.decrement();
                        // 偏移量也减 1
                        mod--;
                    }
                }
            }
        }
        // 没有权重则 调用次数 % 实例数量 对应下标的实例返回
        // Round robin
        return invokers.get(currentSequence % length);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值