前言: 在生產環境中,未避免單點故障,每個微服務都會做高可用部署。 通白的說,就是每一個一模一樣的服務會根據需求提供多分在多台機器上。 那麼在大併發的情況下,如何分配服務可以快速得到響應,就成為了我們要解決的問題。 Ribbon就是一款優秀的客戶端負載均衡機制。 什麼是客戶端負載均衡呢? 就是由服務 ...
前言:
在生產環境中,未避免單點故障,每個微服務都會做高可用部署。
通白的說,就是每一個一模一樣的服務會根據需求提供多分在多台機器上。
那麼在大併發的情況下,如何分配服務可以快速得到響應,就成為了我們要解決的問題。
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;
@RestController
public 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;
@RestController
public 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;
@RestController
public 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;
@RestController
public class HelloController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/hello")
public List<String> sayHello() {
List<String> 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;
@Configuration
public 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;
@Configuration
public 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;
@Configuration
public 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;
@Configuration
public 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,所以它也繼承了“先過濾清單,再輪詢選擇”的基本處理邏輯。 |