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);
}
}