Dubbo负载均衡

导言

Dubbo架构,基本的角色分为三者:

  1. 服务提供者Provider
  2. 服务消费者Consumer
  3. 注册中心

Consumer注册过程

  1. Consumer启动以后,和注册中心建立长连接;
  2. 注册中心会把Consumer订阅的服务的当前正常在线的Provider的列表提供名单提供给Consumer;
  3. Consumer会和每个正常在线的Provider建立一个或者多个TCP长连接;

负载均衡

负载均衡的具体逻辑是在Provider服务端进行配置。

模式 功能 使用场景 优点 缺点
Random 随机选择 缺省
RoundRobin 按公约后的权重设置轮循比率
LeastActive 根据请求调用的次数计数 处理请求更慢的节点会受到更少的请求
ConsistentHash 相同参数的请求总是发到同一提供者 当某一台提供者挂时,不会引起剧烈变动

具体的配置方法:

<dubbo:service interface="com.test.api.XxService" loadbalance="random">
    <dubbo:method ... />
</dubbo:service>

内部实现

Random Select策略的实现

    protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
        int length = invokers.size(); // Number of invokers
        int totalWeight = 0; // The sum of weights
        boolean sameWeight = true; // Every invoker has the same weight?
        for (int i = 0; i < length; i++) {
            int weight = getWeight(invokers.get(i), invocation);
            totalWeight += weight; // Sum
            if (sameWeight && i > 0
                    && weight != getWeight(invokers.get(i - 1), invocation)) {
                sameWeight = false;
            }
        }
        if (totalWeight > 0 && !sameWeight) {
            // If (not every invoker has the same weight & at least one invoker's weight>0), select randomly based on totalWeight.
            int offset = random.nextInt(totalWeight);
            // Return a invoker based on the random value.
            for (int i = 0; i < length; i++) {
                offset -= getWeight(invokers.get(i), invocation);
                if (offset < 0) {
                    return invokers.get(i);
                }
            }
        }
        // If all invokers have the same weight value or totalWeight=0, return evenly.
        return invokers.get(random.nextInt(length));
    }

算法伪代码:

获得provider的数量
for invoker in invokers:
	获得weight
	更新总weight
	比较invoker的权重,和之前的invoker的权重是否相同
		不同的话:sameWeight=false
if totalWeight > 0 && sameWeight == fase:
	根据权重生成一个随机值
if sameWeight == true:
	返回一个随机的invoker

getWeight功能

    protected int getWeight(Invoker<?> invoker, Invocation invocation) {
        int weight = invoker.getUrl().getMethodParameter(invocation.getMethodName(), Constants.WEIGHT_KEY, Constants.DEFAULT_WEIGHT);
        if (weight > 0) {
            long timestamp = invoker.getUrl().getParameter(Constants.REMOTE_TIMESTAMP_KEY, 0L);
            if (timestamp > 0L) {
                int uptime = (int) (System.currentTimeMillis() - timestamp);
                int warmup = invoker.getUrl().getParameter(Constants.WARMUP_KEY, Constants.DEFAULT_WARMUP);
                if (uptime > 0 && uptime < warmup) {
                    weight = calculateWarmupWeight(uptime, warmup, weight);
                }
            }
        }
        return weight;
    }

算法伪代码:

从provider提供的参数中获得,该方法设置的权重
如果权重>0
	获取服务注册是的时间timestamp
	如果timestamp>0
		计算该provider上线的时间
		获得该Provider的warmUp的参数
		如果上线的时间<warmUp的参数
			根据warmup重新计算权重
返回权重
		

资料

dubbo官方负载均衡资料

csdn-dubbo负载均衡模式

posted on 2018-04-02 19:29  threesig  阅读(200)  评论(0)    收藏  举报

导航