前言:
在生产环境中,未避免单点故障,每个微服务都会做高可用部署。
通白的说,就是每一个一模一样的服务会根据需求提供多分在多台机器上。
那么在大并发的情况下,如何分配服务可以快速得到响应,就成为了我们要解决的问题。
Ribbon就是一款优秀的客户端负载均衡机制。
什么是客户端负载均衡呢?
就是由服务的消费方来设定负载均衡策略,选择服务。
就像我们去超市买东西进行结账时,选择人少的柜台排队。
我们是消费方,排哪个队有我们自己决定。
配置测试环境:
1.配置三台服务提供者机器
2.修改端口号分别为:8001,8002,8003
3.修改HelloController返回字符串内容
(1)8001:
package com.xm.cloud.controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class HelloController { @GetMapping("/hello") public String sayHello() { return "Hello Spring Cloud! 001号机器"; }}
(2)8002:
package com.xm.cloud.controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class HelloController { @GetMapping("/hello") public String sayHello() { return "Hello Spring Cloud! 002号机器"; }}
(3)8003:
package com.xm.cloud.controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class HelloController { @GetMapping("/hello") public String sayHello() { return "Hello Spring Cloud! 003号机器"; }}
4.修改消费服务HelloController
package com.xm.cloud.controller;import java.util.ArrayList;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;@RestControllerpublic class HelloController { @Autowired private RestTemplate restTemplate; @GetMapping("/hello") public ListsayHello() { List list = new ArrayList<>(); for(int i=0;i<30;i++) { list.add(restTemplate.getForObject("http://CL-HELLO-PRODUCER/hello", String.class)); } return list; }}
实践:
1.测试默认的负载均衡策略(轮询:RoundRobinRule):
(1)默认cfg:
package com.xm.cloud.cfg;import org.springframework.cloud.client.loadbalancer.LoadBalanced;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.client.RestTemplate;@Configurationpublic class MyConfiguration { @LoadBalanced @Bean RestTemplate restTemplate() { return new RestTemplate(); }}
(2)测试:localhost:8080/hello
0 | "Hello Spring Cloud! 002号机器" |
---|---|
1 | "Hello Spring Cloud! 003号机器" |
2 | "Hello Spring Cloud! 001号机器" |
3 | "Hello Spring Cloud! 002号机器" |
4 | "Hello Spring Cloud! 003号机器" |
5 | "Hello Spring Cloud! 001号机器" |
6 | "Hello Spring Cloud! 002号机器" |
7 | "Hello Spring Cloud! 003号机器" |
8 | "Hello Spring Cloud! 001号机器" |
9 | "Hello Spring Cloud! 002号机器" |
10 | "Hello Spring Cloud! 003号机器" |
11 | "Hello Spring Cloud! 001号机器" |
12 | "Hello Spring Cloud! 002号机器" |
13 | "Hello Spring Cloud! 003号机器" |
14 | "Hello Spring Cloud! 001号机器" |
15 | "Hello Spring Cloud! 002号机器" |
16 | "Hello Spring Cloud! 003号机器" |
17 | "Hello Spring Cloud! 001号机器" |
18 | "Hello Spring Cloud! 002号机器" |
19 | "Hello Spring Cloud! 003号机器" |
20 | "Hello Spring Cloud! 001号机器" |
21 | "Hello Spring Cloud! 002号机器" |
22 | "Hello Spring Cloud! 003号机器" |
23 | "Hello Spring Cloud! 001号机器" |
24 | "Hello Spring Cloud! 002号机器" |
25 | "Hello Spring Cloud! 003号机器" |
26 | "Hello Spring Cloud! 001号机器" |
27 | "Hello Spring Cloud! 002号机器" |
28 | "Hello Spring Cloud! 003号机器" |
29 | "Hello Spring Cloud! 001号机器" |
2.测试随机策略(RandomRule):
(1)修改cfg:
package com.xm.cloud.cfg;import org.springframework.cloud.client.loadbalancer.LoadBalanced;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.client.RestTemplate;import com.netflix.loadbalancer.IRule;import com.netflix.loadbalancer.RandomRule;@Configurationpublic class MyConfiguration { @LoadBalanced @Bean RestTemplate restTemplate() { return new RestTemplate(); } @Bean public IRule myRule() { return new RandomRule(); }}
(2)测试结果:
0 | "Hello Spring Cloud! 002号机器" |
---|---|
1 | "Hello Spring Cloud! 003号机器" |
2 | "Hello Spring Cloud! 003号机器" |
3 | "Hello Spring Cloud! 002号机器" |
4 | "Hello Spring Cloud! 003号机器" |
5 | "Hello Spring Cloud! 001号机器" |
6 | "Hello Spring Cloud! 001号机器" |
7 | "Hello Spring Cloud! 002号机器" |
8 | "Hello Spring Cloud! 002号机器" |
9 | "Hello Spring Cloud! 002号机器" |
10 | "Hello Spring Cloud! 001号机器" |
11 | "Hello Spring Cloud! 003号机器" |
12 | "Hello Spring Cloud! 002号机器" |
13 | "Hello Spring Cloud! 003号机器" |
14 | "Hello Spring Cloud! 003号机器" |
15 | "Hello Spring Cloud! 002号机器" |
16 | "Hello Spring Cloud! 001号机器" |
17 | "Hello Spring Cloud! 001号机器" |
18 | "Hello Spring Cloud! 002号机器" |
19 | "Hello Spring Cloud! 003号机器" |
20 | "Hello Spring Cloud! 001号机器" |
21 | "Hello Spring Cloud! 003号机器" |
22 | "Hello Spring Cloud! 002号机器" |
23 | "Hello Spring Cloud! 002号机器" |
24 | "Hello Spring Cloud! 003号机器" |
25 | "Hello Spring Cloud! 002号机器" |
26 | "Hello Spring Cloud! 001号机器" |
27 | "Hello Spring Cloud! 001号机器" |
28 | "Hello Spring Cloud! 002号机器" |
29 | "Hello Spring Cloud! 001号机器" |
3.测试最佳可用策略(最佳可用):
(1)修改cfg:
package com.xm.cloud.cfg;import org.springframework.cloud.client.loadbalancer.LoadBalanced;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.client.RestTemplate;import com.netflix.loadbalancer.BestAvailableRule;import com.netflix.loadbalancer.IRule;import com.netflix.loadbalancer.RandomRule;@Configurationpublic class MyConfiguration { @LoadBalanced @Bean RestTemplate restTemplate() { return new RestTemplate(); } @Bean public IRule myRule() { return new BestAvailableRule(); }}
(2)测试结果:
0 | "Hello Spring Cloud! 003号机器" |
---|---|
1 | "Hello Spring Cloud! 003号机器" |
2 | "Hello Spring Cloud! 003号机器" |
3 | "Hello Spring Cloud! 003号机器" |
4 | "Hello Spring Cloud! 003号机器" |
5 | "Hello Spring Cloud! 003号机器" |
6 | "Hello Spring Cloud! 003号机器" |
7 | "Hello Spring Cloud! 003号机器" |
8 | "Hello Spring Cloud! 003号机器" |
9 | "Hello Spring Cloud! 003号机器" |
10 | "Hello Spring Cloud! 003号机器" |
11 | "Hello Spring Cloud! 003号机器" |
12 | "Hello Spring Cloud! 003号机器" |
13 | "Hello Spring Cloud! 003号机器" |
14 | "Hello Spring Cloud! 003号机器" |
15 | "Hello Spring Cloud! 003号机器" |
16 | "Hello Spring Cloud! 003号机器" |
17 | "Hello Spring Cloud! 003号机器" |
18 | "Hello Spring Cloud! 003号机器" |
19 | "Hello Spring Cloud! 003号机器" |
20 | "Hello Spring Cloud! 003号机器" |
21 | "Hello Spring Cloud! 003号机器" |
22 | "Hello Spring Cloud! 003号机器" |
23 | "Hello Spring Cloud! 003号机器" |
24 | "Hello Spring Cloud! 003号机器" |
25 | "Hello Spring Cloud! 003号机器" |
26 | "Hello Spring Cloud! 003号机器" |
27 | "Hello Spring Cloud! 003号机器" |
28 | "Hello Spring Cloud! 003号机器" |
29 | "Hello Spring Cloud! 003号机器" |
4.测试重试负载均衡策略(RetryRule)
(1)修改cfg:
package com.xm.cloud.cfg;import org.springframework.cloud.client.loadbalancer.LoadBalanced;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.client.RestTemplate;import com.netflix.loadbalancer.BestAvailableRule;import com.netflix.loadbalancer.IRule;import com.netflix.loadbalancer.RandomRule;import com.netflix.loadbalancer.RetryRule;@Configurationpublic class MyConfiguration { @LoadBalanced @Bean RestTemplate restTemplate() { return new RestTemplate(); } @Bean public IRule myRule() { return new RetryRule(); }}
(2)测试结果:
0 | "Hello Spring Cloud! 001号机器" |
---|---|
1 | "Hello Spring Cloud! 002号机器" |
2 | "Hello Spring Cloud! 003号机器" |
3 | "Hello Spring Cloud! 001号机器" |
4 | "Hello Spring Cloud! 002号机器" |
5 | "Hello Spring Cloud! 003号机器" |
6 | "Hello Spring Cloud! 001号机器" |
7 | "Hello Spring Cloud! 002号机器" |
8 | "Hello Spring Cloud! 003号机器" |
9 | "Hello Spring Cloud! 001号机器" |
10 | "Hello Spring Cloud! 002号机器" |
11 | "Hello Spring Cloud! 003号机器" |
12 | "Hello Spring Cloud! 001号机器" |
13 | "Hello Spring Cloud! 002号机器" |
14 | "Hello Spring Cloud! 003号机器" |
15 | "Hello Spring Cloud! 001号机器" |
16 | "Hello Spring Cloud! 002号机器" |
17 | "Hello Spring Cloud! 003号机器" |
18 | "Hello Spring Cloud! 001号机器" |
19 | "Hello Spring Cloud! 002号机器" |
20 | "Hello Spring Cloud! 003号机器" |
21 | "Hello Spring Cloud! 001号机器" |
22 | "Hello Spring Cloud! 002号机器" |
23 | "Hello Spring Cloud! 003号机器" |
24 | "Hello Spring Cloud! 001号机器" |
25 | "Hello Spring Cloud! 002号机器" |
26 | "Hello Spring Cloud! 003号机器" |
27 | "Hello Spring Cloud! 001号机器" |
28 | "Hello Spring Cloud! 002号机器" |
29 | "Hello Spring Cloud! 003号机器" |
5.规则比较
策略 | 介绍 |
---|---|
RoundRobinRule | 简单轮询服务列表来选择服务器。它是Ribbon默认的负载均衡规则。 |
RandomRule | 随机选择一个可用的服务器。 |
RetryRule | 默认轮询,重试多次失败的机器从轮询列表中淘汰。 |
BestAvailableRule | 忽略哪些短路的服务器,并选择并发数较低的服务器。 |
ZoneAvoidanceRule | 以区域可用的服务器为基础进行服务器的选择。使用Zone对服务器进行分类,这个Zone可以理解为一个机房、一个机架等。 |
WeightedResponseTimeRule | 为每一个服务器赋予一个权重值。服务器响应时间越长,这个服务器的权重就越小。这个规则会随机选择服务器,这个权重值会影响服务器的选择。 |
AvailabilityFilteringRule | 该策略继承自上面介绍的抽象策略PredicateBasedRule,所以它也继承了“先过滤清单,再轮询选择”的基本处理逻辑。 |