SpringCloud-Ribbon的负载均衡策略---RoundRobinRule
Ribbon的负载均衡算法主要有7种,见下图
1、RoundRobinRule(轮询方式)
主要原理:简单一点说就是,该请求请求次数与集群机器数量取模结果对应机器下标。
源码如下:
打开RoundRobinRule.java public class RoundRobinRule extends AbstractLoadBalancerRule { // 原子下标初始值,用于确定最后返回哪个的server private AtomicInteger nextServerCyclicCounter; // 通过默认构造器进行初始化 public RoundRobinRule() { nextServerCyclicCounter = new AtomicInteger(0); } // 传入负载均衡算法lb public Server choose(ILoadBalancer lb, Object key) { // 如果没有传入进行报错提示并返回 if (lb == null) { log.warn("no load balancer"); return null; } // 定义一个server,用于最后返回,供消费者实际调用 Server server = null; // 定义一个count计数器 int count = 0; while (server == null && count++ < 10) { // 获取up and reachable状态的Server List<Server> reachableServers = lb.getReachableServers(); // 获取所有的server List<Server> allServers = lb.getAllServers(); // 获取正常状态server的数量upCount int upCount = reachableServers.size(); // 获取所有服务的数量serverCount int serverCount = allServers.size(); // 二者有一个为0,都表示当前服务不可用,保错并返回 if ((upCount == 0) || (serverCount == 0)) { log.warn("No up servers available from load balancer: " + lb); return null; } // 获取server的角标 int nextServerIndex = incrementAndGetModulo(serverCount); // 根据角标确定server信息 server = allServers.get(nextServerIndex); 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) { // 自旋锁 + CAS实现获取index for (;;) { int current = nextServerCyclicCounter.get(); int next = (current + 1) % modulo; if (nextServerCyclicCounter.compareAndSet(current, next)) return next; } } // 通过重写choose返回server信息 @Override public Server choose(Object key) { return choose(getLoadBalancer(), key); } }