Netflix Ribbon 負載均衡 概述 與 基本使用

目錄

netflix ribbon 負載均衡

netflix Ribbon 基本使用

Ribbon 超時時間配置


本文環境:Java jdk 8 + Spring boot 2.1.3 + spring cloud Greenwich.SR1 + spring 5.1.5。

netflix ribbon 負載均衡

1、ribbon 與 eureka 一樣都是 netflix 下的子項目,spring cloud 對它們進行了集成。

2、ribbon 是一個基於 HTTP 和 TCP 的客戶端負載均衡工具,可以輕鬆地將面向服務的 REST 模版請求自動轉換成客戶端負載均衡的服務調用。

3、Spring Cloud Ribbon 雖然只是一個工具類框架,它不像服務註冊中心、配置中心、API網關那樣需要獨立部署,但是它幾乎存在於每一個Spring Cloud構建的微服務和基礎設施中。因爲微服務間的調用,API 網關的請求轉發等內容,實際上都是通過 Ribbon 實現。

4、nginx 在服務端實現負載均衡,ribbon 在客戶端提供負載均衡。即客戶端程序使用 ribbon 後,就會自動對多個節點微服務進行負載均衡。

5、負載均衡有好幾種實現策略,常見的有:隨機 (Random)、輪詢 (RoundRobin)、一致性哈希(ConsistentHash)、哈希 (Hash)、加權(Weighted)。默認是輪詢。官網地址:

https://github.com/Netflix/ribbon

https://spring.io/projects/spring-cloud-netflix

https://cloud.spring.io/spring-cloud-static/spring-cloud-netflix/2.1.0.RELEASE/single/spring-cloud-netflix.html#spring-cloud-ribbon

6、使用下面的命令啓動多個微服務節點,動態修改應用端口以及實例名稱。

java -jar eurekaclient_food-0.0.1-SNAPSHOT.jar --server.port=9396 --eureka.instance.instance-id=changSha-food-9396
java -jar eurekaclient_food-0.0.1-SNAPSHOT.jar --server.port=9397 --eureka.instance.instance-id=changSha-food-9397

如上所示此時 Eureka 服務端可以看到微服務 EUREKA-CLIENTFOOD 下面有3個節點。

netflix Ribbon 基本使用

1、Ribbon 是客戶端實現的負載均衡,也就是誰發起請求,誰自己實現負載均衡,所以 eurekaclient_cat 向 eurekaclient_food 發起請求,則應該修改 eurekaclient_cat 應用。第一步應該引入 Ribbon 組件,但是 eureka 組件默認已經依賴了 ribbon 組件,所以只要引入了 eureka 就已經引入了 ribbon。

......
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
......

2、修改 eurekaclient_cat 創建 RestTemplate 實例的代碼,加上 @LoadBalanced 使 RestTemplate 具有負載均衡的能力。

    /**
     * @SpringBootApplication 註解自己依賴了 @Configuration 註解,所以可以直接在啓動類上使用 @Bean 註解
     * 當然也可以新建一個配置類(@Configuration) 專門管理需要創建的實例
     * @Bean 作用就是使用 DI 往 spring 容器中傳教實例,以後可以直接使用 @Resource 取值使用。
     * <p>
     * LoadBalanced:英文就是負載均衡的意思,@LoadBalanced 註解表示 RestTemplate 具有負載均衡的能力。
     * 意味着 RestTemplate 每次發送 http 請求時,都會根據 ribbon 的負載均衡機制向微服務下的某臺節點服務器發送請求
     */
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        //RestTemplate 有3個構造器,這裏使用無參構造器,底層使用 jdk 原生的 java.net 下 api 進行 http 操作
        return new RestTemplate();
    }

3、然後修改 RestTemplate 發起 http 請求的代碼,將原來寫死的 ip與端口換成微服務的名稱,本文是爲了演示簡單,微服務名稱直接寫死了,實際開發中可以從配置文件中獲取:

    @Resource
    private RestTemplate restTemplate;

    //通過 id 獲取貓咪信息。這裏只是簡單的模擬,並不是操作數據庫
    //請求地址:http://localhost:9394/getCatById?id=110
    @GetMapping("getCatById")
    public String getCatById(String id) throws IOException {
        //貓咪的基本信息,這裏直接設置
        JsonNodeFactory nodeFactory = JsonNodeFactory.instance;
        ObjectNode objectNode = nodeFactory.objectNode();
        objectNode.put("id", id);
        objectNode.put("color", "white");
        objectNode.put("age", 0.2);

        //貓咪的食譜/菜譜信息調用 eurekaclient_food 微服務進行獲取。
        //未使用負載均衡時的地址:http://localhost:9395/getHunanCuisine。使用負載均衡後,其中的 ip:port 必須使用微服務名稱代替
        //EUREKA-CLIENT-FOOD 是在註冊中心註冊好的微服務名稱(不是節點名稱),也就是微服務配置文件中使用 spring.application.name 配置的名稱
        String foodMenu = restTemplate.getForObject("http://EUREKA-CLIENT-FOOD/getHunanCuisine", String.class);
        if (!StringUtils.isEmpty(foodMenu)) {
            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode jsonNode = objectMapper.readTree(foodMenu);//先將 json 字符串專戶 json 節點對象
            objectNode.putPOJO("menu", jsonNode);//對象節點插入子節點
        }
        return objectNode.toString();
    }

5、代碼很簡單,修改兩處就好了,接下來訪問測試:

可以看出 ribbon 默認採用的輪詢的策略,即對集羣的服務輪流進行訪問。

注意:具有負載均衡後的 RestTemplate 請求時只能使用微服務名稱,無法再直接使用 ip:port 的形式,如果應用中還需要直接使用 ip 請求,則可以再提供一個非負載均衡的 RestTemplate 實例即可,使用時根據方法名注入。

    @Bean
    RestTemplate restTemplateNotBalance() {
        return new RestTemplate();
    }

帶負載均衡(@LoadBalanced)的 RestTemplate 必須使用微服務名稱發起請求,不能使用 ip:port
不帶負載均衡(@LoadBalanced)的 RestTemplate 不能使用微服務名稱發起請求,只能使用 ip:port

更多負載均衡策略可以參考《Ribbon 負載均衡策略 與 脫離 Eureka 使用、LoadBalancerClient

演示源碼 github 地址:https://github.com/wangmaoxiong/ribbon_study

Ribbon 超時時間配置

官網:/spring-cloud-netflix/2.1.0.RELEASE/single/spring-cloud-netflix.html#_zuul_timeouts

ribbon:
  ConnectTimeout: 3000  #連接超時時間
  ReadTimeout: 60000    #讀取超時時間
  SocketTimeout: 60000  #socket 超時時間

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章