1.Ribbon负载均衡原理
默认负载轮训算法: rest接口第几次请求数 % 服务器集群总数量 = 实际调用服务器位置下标
List<Servicelnstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
list.get(index)获取下标index,决定被访问的机器。
实例:eureka服务中心集群了payment微服务8001和8002,则队列为
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,则获得服务地址为127.0.0.1:8001
当总请求数位2时:2%2=0对应下标位置为0,则获得服务地址为127.0.0.1:8002
当总请求数位3时:3%2=1对应下标位置为1,则获得服务地址为127.0.0.1:8001
当总请求数位4时:4%2=0对应下标位置为0,则获得服务地址为127.0.0.1:8002
如此类推…固默认算法下,两台机器交替被访问。
每次当服务重启动后rest接口计数从1重新开始。
2.Ribbon源码解析
1.核心组件IRule:
2.随机算法源码:
下方算法为随机轮询算法选择机器的具体代码:
首先确定调用微服务的名称,如无,返回错误参数。
然后根据微服务的名称,传入server微服务机器数,生成list数组。
再把参数(机器数量)传入
incrementAndGetModulo(int modulo)
算法中,使用取余并取下标的算法得到index值,再进行比较和赋值。
把index值传回
nextServerIndex
变量中,再根据server.get(index)选择出所需要的机器。
3.手写Ribbon轮询算法
1.ApplicationContextConfig去掉注解@LoadBalanced,OrderMain80去掉注解@RibbonClient
2.编写lb接口,传入server名参数:
3.实现lb接口:
主要有两个方法,getandincrement()方法用以统计访问次数,返回当前访问次数值。直至取到期望值,跳出循环。
继承接口的方法instance()传入当前server服务的list数组(需要使用其数量),调用getandincrement()方法,套用轮询公式,获取index值,再根据index值返回server名给方法。
4.修改controller类:
如服务失效,返回空值;服务生效,传入服务名,调用loadbalancer(自己编写的轮询算法)。
5.进行测试。不停地刷新http://localhost/consumer/payment/lb,可以看到8001/8002交替出现。