前言
主要分享Ribbon默认负载轮询算法原理,源码查看(负载均衡算法很多,先介绍一下轮询叭),请多指教!
提示:以下是本篇文章正文内容,下面案例可供参考
一、Ribbon是什么?
Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。
二、负载均衡轮询算法原理
公式:rest接口第几次请求数 % 服务器集群总数量 = 实际调用服务器位置下标,每次重新启动后rest接口计数从1开始。
代码如下(示例):
List<ServiceInstance> instances = discoverClient.getInstances("CLOUD-PAYMENT-SERVICE");
如: List[0] instances = 127.0.0.1:8002
List[1] instances = 127.0.0.1:8001
8001 + 8002 组合成为集群,它们共计2台机器,集群总数为2,按照轮询算法原理:
当总请求数为1时:1%2=1 对应下标位置为1,则获得服务器地址为list.get(1)=127.0.0.1:8001
当总请求数为2时:2%2=0 对应下标位置为0,则获得服务器地址为list.get(0)=127.0.0.1:8002
当总请求数为3时:3%2=1 对应下标位置为1,则获得服务器地址为list.get(1)=127.0.0.1:8001
当总请求数为4时:4%2=0 对应下标位置为0,则获得服务器地址为list.get(0)=127.0.0.1:8002
如此类推......
三.RoundRobinRule源码
1.负载均衡类图
源码中可以看到默认轮询类RoundRobinRule继承了负载均衡策略的抽象类AbstractLoadBalancerRule实现了IRule接口。
选择哪一个对外提供服务choose方法???(下图)
public Server choose(ILoadBalancer lb, Object key) {
if(lb == null) {
log.warn("no load balancer");
return null;
} else {
Server server = null;
int count = 0;
while(true) {
if(server == null && count++ < 10) {
//从ILoadBalancer接口中获取当前系统存货的服务
List<Server> reachableServers = lb.getReachableServers();
List<Server> allServers = lb.getAllServers();
int upCount = reachableServers.size();
//获取到所有服务器的size(当前我的数量为2==>8001,8002)
int serverCount = allServers.size();
if(upCount != 0 && serverCount != 0) {
/*得到list下标 incrementAndGetModulo这个方法内部用到了自旋锁(我稍后补习)*/
int nextServerIndex = this.incrementAndGetModulo(serverCount);
//nextServerIndex返回1 根据下标allServers.get(1)=>我们的8001服务
server = (Server)allServers.get(nextServerIndex);
if(server == null) {
Thread.yield();
} else {
if(server.isAlive() && server.isReadyToServe()) {
return server;
}
server = null;
}
continue;
}
log.warn("No up servers available from load balancer: " + lb);
return null;
}
if(count >= 10) {
log.warn("No available alive servers after 10 tries from load balancer: " + lb);
}
//8001服务
return server;
}
}
}
private int incrementAndGetModulo(int modulo) {//modulo=2
int current;
int next;
do {
//nextServerCyclicCounter默认为0
current = this.nextServerCyclicCounter.get();
//此处就是我们之前提到的公式:(0+1)%2=1 下标为1
next = (current + 1) % modulo;
} while(!this.nextServerCyclicCounter.compareAndSet(current, next));
return next;
}
2.Feign(小知识)
feign也可以使用ribbon的负载均衡策略,feign整合了ribbon,同时具备了负载均衡功能!(如图)
总结
ok,以上就是要分享的内容,希望了帮到大家(喜欢记得三连呦!!!耶✌我的域名:https://wzdhhp.blog.csdn.net/)