框架篇-springcloud ribbon

负载均衡算法

IRule接口下的 RoundRobinRule
public Server choose(ILoadBalancer lb, Object key) {
    if (lb == null) {
        log.warn("no load balancer");
        return null;
    }

    Server server = null;
    int count = 0;
   //重试机制 重试十次尝试获取service
    while (server == null && count++ < 10) {
        List reachableServers = lb.getReachableServers();
        List allServers = lb.getAllServers();
        int upCount = reachableServers.size();
        int serverCount = allServers.size();

        if ((upCount == 0) || (serverCount == 0)) {
            log.warn("No up servers available from load balancer: " + lb);
            return null;
        }

        //轮询的核心方法
        int nextServerIndex = incrementAndGetModulo(serverCount);
        server = allServers.get(nextServerIndex);

        //如果取到的是null 则放弃时间片后在重试
        if (server == null) {
            /* Transient. */
            Thread.yield();
            continue;
        }

        if (server.isAlive() && (server.isReadyToServe())) {
            return (server);
        }

        // Next.
        server = null;
    }

    if (count >= 10) {
        log.warn("No available alive servers after 10 tries from load balancer: "
                + lb);
    }
    return server;
}

private int incrementAndGetModulo(int modulo) {
        for (;;) {
            //轮询的核心方法 相当于i++ % m; i++取模则会在0~m之间循环
            //nextServerCyclicCounter是原子类
            int current = nextServerCyclicCounter.get();
            int next = (current + 1) % modulo;
            if (nextServerCyclicCounter.compareAndSet(current, next))
                return next;
        }
    }
RandomRule
//随机算法 就是随机一个下标值
int index = rand.nextInt(serverCount);
server = upList.get(index);

响应时间权重算法WeightedResponseTimeRule

这是一个复杂算法

每个服务的权重怎么来

从eureka中取服务的响应

public void maintainWeights() {
  //...前中后都有省略
  for (Server server : nlb.getAllServers()) {
      // this will automatically load the stats if not in cache
      //从服务管理中心(eureka) 取每个实例的状态
      ServerStats ss = stats.getSingleServerStat(server);
      //因为常规的权重算法 默认权重越大 则更高几率访问 所以在这里计算一个总时间来反算权重大小
        //另外 也可以直接创建一个list 用。。。。
      totalResponseTime += ss.getResponseTimeAvg();
  }

  Double weightSoFar = 0.0;

  // create new list and hot swap the reference
  List finalWeights = new ArrayList();
  for (Server server : nlb.getAllServers()) {
    ServerStats ss = stats.getSingleServerStat(server);
    double weight = totalResponseTime - ss.getResponseTimeAvg();
    weightSoFar += weight;
    finalWeights.add(weightSoFar);   
  }
  setWeights(finalWeights);
}

你可能感兴趣的:(框架)