1. 程式人生 > >3.Spring Cloud初相識--------Ribbon客戶端負載均衡

3.Spring Cloud初相識--------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,所以它也繼承了“先過濾清單,再輪詢選擇”的基本處理邏輯。

自定義負載均衡策略步驟

1.實現IRule介面

2.cfg註冊覆蓋預設負載均衡策略