5分pk10计划三期必中 _Spring Clould负载均衡重要组件:Ribbon中重要类的用法

  • 时间:
  • 浏览:0

    Ribbon是Spring Cloud Netflix全家桶中负责负载均衡的组件,它是一组类库的集合。通过Ribbon,程序池池员能在不涉及到具体实现细节的基础上“透明”地用到负载均衡,而不须在项目里不要 地编写实现负载均衡的代码。

    比如,在某个所含Eureka和Ribbon的集群中,某个服务(可不可不都可以理解成5个 多jar包)被部署在多台服务器上,当多个服务使用者一齐调用该服务时,哪些地方地方并发的请求能被用有有一种合理的策略转发到各台服务器上。

    事实上,在使用Spring Cloud的其它各种组件时,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 都能看一遍Ribbon的痕迹,比如Eureka能和Ribbon整合,而在后文里将提到的提供网关功能Zuul组件在转发请求时,也可不可不都可以整合Ribbon从而达到负载均衡的效果。

    从代码层面来看,Ribbon有如下5个 多比较重要的接口。

    第一,ILoadBalancer,这也叫负载均衡器,通过它,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 能在项目里根据特定的规则合理地转发请求,常见的实现类有BaseLoadBalancer。

    第二,IRule,类式 接口有多个实现类,比如RandomRule和RoundRobinRule,哪些地方地方实现类具体地定义了诸如“随机“和”轮询“等的负载均衡策略,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 还能重写该接口里的方法来自定义负载均衡的策略。

在BaseLoadBalancer类里,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 能通过IRule的实现类设置负载均衡的策略,曾经该负载均衡器就能据此合理地转发请求。

    第三,IPing接口,通过该接口,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 能获取到当前哪些地方服务器是可用的,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 都可不可不都可以通过重写该接口里的方法来自定义判断服务器与非 可用的规则。在BaseLoadBalancer类里,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 同样能通过IPing的实现类设置判断服务器与非 可用的策略。    

1 ILoadBalancer:负载均衡器接口

    在Ribbon里,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 还可不可不都可以通过ILOadBalancer类式 接口以基于特定的负载均衡策略来选者服务器。

    通过下面的ILoadBalancerDemo.java,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 来看下类式 接口的基本用法。类式 类是装在 4.2部分创建的RabbionBasicDemo项目里,代码如下。    

1    //省略必要的package和import代码
2    public class ILoadBalancerDemo {
3        public static void main(String[] args){
4            //创建ILoadBalancer的对象 
5             ILoadBalancer loadBalancer = new BaseLoadBalancer();
6            //定义5个

多服务器列表
7               List<Server> myServers = new ArrayList<Server>();
8            //创建5个

多Server对象
9            Server s1 = new Server("ekserver1",30003000);
10             Server s2 = new Server("ekserver2",30003000);
11            //5个

多server对象装在



List类型的myServers对象里   
12             myServers.add(s1);
13             myServers.add(s2);
14            //把myServers装在



负载均衡器
15            loadBalancer.addServers(myServers);
16            //在for循环里发起10次调用
17            for(int i=0;i<10;i++){
18             //用基于默认的负载均衡规则获得Server类型的对象
19                Server s = loadBalancer.chooseServer("default");
20             //输出IP地址和端口号
21                System.out.println(s.getHost() + ":" + s.getPort());
22            }        
23       }
24    }

     在第5行里,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 创建了BaseLoadBalancer类型的loadBalancer对象,而BaseLoadBalancer是负载均衡器ILoadBalancer接口的实现类。

    在第6到第13行里,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 创建了5个 多Server类型的对象,并把它们装在 了myServers里,在第15行里,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 把List类型的myServers对象装在 了负载均衡器里。

    在第17到22行的for循环里,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 通过负载均衡器模拟了10次选者服务器的动作,具体而言,是在第19行里,通过loadBalancer的chooseServer方法以默认的负载均衡规则选者服务器,在第21行里,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 是用“打印”类式 动作来模拟实际的“使用Server对象正确处理请求”的动作。

    上述代码的运行结果如下所示,其中我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 能看一遍,loadBalancer类式 负载均衡器把10次请求均摊到了2台服务器上,从中其实能看一遍 “负载均衡”的效果。

    第二,IRule,类式 接口有多个实现类,比如RandomRule和RoundRobinRule,哪些地方地方实现类具体地定义了诸如“随机“和”轮询“等的负载均衡策略,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 还能重写该接口里的方法来自定义负载均衡的策略。

    在BaseLoadBalancer类里,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 能通过IRule的实现类设置负载均衡的策略,曾经该负载均衡器就能据此合理地转发请求。

    第三,IPing接口,通过该接口,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 能获取到当前哪些地方服务器是可用的,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 都可不可不都可以通过重写该接口里的方法来自定义判断服务器与非 可用的规则。在BaseLoadBalancer类里,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 同样能通过IPing的实现类设置判断服务器与非 可用的策略。  

1    ekserver2:30003000
2    ekserver1:30003000
3    ekserver2:30003000
4    ekserver1:30003000
5    ekserver2:30003000
6    ekserver1:30003000
7    ekserver2:30003000
8    ekserver1:30003000
9    ekserver2:30003000
10   ekserver1:30003000

2 IRule:定义负载均衡规则的接口

    在Ribbon里,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 可不可不都可以通过定义IRule接口的实现类来给负载均衡器设置相应的规则。在下表里,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 能看一遍IRule接口的其他常用的实现类。

实现类的名字

负载均衡的规则

RandomRule

采用随机选者的策略

RoundRobinRule

采用轮询策略

RetryRule

采用该策略时,会所含重试动作

AvailabilityFilterRule

会过滤些多次连接失败和请求并发数匮乏的服务器

WeightedResponseTimeRule

根据平均响应时间为每个服务器设置5个 多权重,根据该权重值优先选者平均响应时间较小的服务器

ZoneAvoidanceRule

优先把请求分配到和该请求具有相同区域(Zone)的服务器上

    在下面的IRuleDemo.java的程序池池里,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 来看下IRule的基本用法。

1    //省略必要的package和import代码
2    public class IRuleDemo {
3        public static void main(String[] args){
4        //请注意这是用到的是BaseLoadBalancer,而也有ILoadBalancer接口
5        BaseLoadBalancer loadBalancer = new BaseLoadBalancer();
6            //声明基于轮询的负载均衡策略
7            IRule rule = new RoundRobinRule();
8        //在负载均衡器里设置策略 
9            loadBalancer.setRule(rule);
10            //如下定义5个Server,并把它们装在



List类型的集合中
11            List<Server> myServers = new ArrayList<Server>();
12            Server s1 = new Server("ekserver1",30003000);
13            Server s2 = new Server("ekserver2",30003000);
14            Server s3 = new Server("ekserver3",30003000);
15            myServers.add(s1);
16            myServers.add(s2);
17            myServers.add(s3);
18            //在负载均衡器里设置服务器的List
19            loadBalancer.addServers(myServers);
20            //输出负载均衡的结果
21            for(int i=0;i<10;i++){
22                Server s = loadBalancer.chooseServer(null);
23                System.out.println(s.getHost() + ":" + s.getPort());    
24          }        
25        }
26    }

    这段代码和上文里的ILoadBalancerDemo.java很类式 ,但有如下的差别点。

    1 在第5行里,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 是通过BaseLoadBalancer类式 类而也有接口来定义负载均衡器,意味是该类所含setRule方法。

    2 在第7行定义了5个 多基于轮询规则的rule对象,并在第9行里把它设置进负载均衡器。

    3 在第19行里,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 是把所含5个Server的List对象装在 负载均衡器,而也有以前的5个 多。可能性这里存粹是为了演示效果,却说 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 就装在 5个 多根本不趋于稳定的“ekserver3”服务器。

    运行该程序池池后,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 可不可不都可以看一遍有10次输出,倘若 其实是按“轮询”的规则有顺序地输出5个服务器的名字。可能性我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 把第7行的代码改成如下,没有就会看一遍 “随机”地输出服务器名。

    IRule rule = new RandomRule();

3  IPing:判断服务器与非 可用的接口

    在项目里,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 一般会让ILoadBalancer接口自动地判断服务器与非 可用(哪些地方地方业务都封装在 Ribbon的底层代码里),此外,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 还可不可不都可以用Ribbon组件里的IPing接口来实现类式 功能。

    在下面的IRuleDemo.java代码里,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 将演示IPing接口的一般用法。    

1    //省略必要的package和import代码
2    class MyPing implements IPing {
3        public boolean isAlive(Server server) {
4             //可能性服务器名是ekserver2,则返回false
5            if (server.getHost().equals("ekserver2")) {
6                return false;
7            }
8            return true;
9        }
10    }

    第2行定义的MyPing类实现了IPing接口,并在第3行重写了其中的isAlive方法。

    在类式 方法里,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 根据服务器名来判断,具体而言,可能性名字是ekserver2,则返回false,表示该服务器不可用,倘若 返回true,表示当前服务器可用。     

11    public class IRuleDemo {
12        public static void main(String[] args) {
13            BaseLoadBalancer loadBalancer = new BaseLoadBalancer();
14            //定义IPing类型的myPing对象
15            IPing myPing = new MyPing(); 
16             //在负载均衡器里使用myPing对象
17            loadBalancer.setPing(myPing);
18             //同样是创建5个

多Server对象并装在



负载均衡器
19            List<Server> myServers = new ArrayList<Server>();
20            Server s1 = new Server("ekserver1", 30003000);
21            Server s2 = new Server("ekserver2", 30003000);
22            Server s3 = new Server("ekserver3", 30003000);
23            myServers.add(s1);
24            myServers.add(s2);
25            myServers.add(s3);
26            loadBalancer.addServers(myServers);
27             //通过for循环多次请求服务器 
28            for (int i = 0; i < 10; i++) {
29                Server s = loadBalancer.chooseServer(null);
300                System.out.println(s.getHost() + ":" + s.getPort());
31            }
32        }
33    }

    在第12行的main函数里,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 在第15行创建了IPing类型的myPing对象,并在第17行把类式 对象装在 了负载均衡器。通过第18到第26行的代码,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 创建了5个 多服务器,并把它们也装在 负载均衡器。

    在第28行的for循环里,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 依然是请求并输出服务器名。可能性这里的负载均衡器loadBalancer中所含了5个 多IPing类型的对象,却说 在根据策略得到服务器后,会根据myPing里的isActive方法来判断该服务器与非 可用。

    可能性在类式 方法里,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 定义了ekServer2这台服务器不可用,却说 负载均衡器loadBalancer对象始终前会把请求发送到该服务器上,也却说 说,在输出结果中,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 前会看一遍“ekserver2:30003000”的输出。

    从中我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 能看一遍IPing接口的一般用法,我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 可不可不都可以通过重写其中的isAlive方法来定义“判断服务器与非 可用“的逻辑,在实际项目里,判断的方法无非是”服务器响应与非 时间过长“或”发往该服务器的请求数与非 不要 “,而哪些地方地方判断方法都封装在 IRule接口以及它的实现类里,却说 在一般的场景中我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 我们歌词 歌词 用到IPing接口。

4  预告&版权申明

     在本周的中间时间里,我将继续给出用Eureka+Ribbon高可用负载均衡架构的搭建方法。

     本文内容摘自当事人写的专业书籍,转载时请一齐引入该版权申明,请勿用于商业用途。