SpringCloud 基礎教程(六)-負載均衡Ribbon

 個人博客:蘭陵笑笑生,歡迎瀏覽博客!java

 上一章 SpringCloud基礎教程(五)-配置中心熱生效和高可用當中,咱們對配置中心進行進行了深刻的瞭解,本章將繼續微服務架構的深刻學習,瞭解在微服務中是如何作到負載均衡的。程序員

前言

 簡單來說,Ribbon是Netflix發佈的開源項目,主要的功能是提供客戶端的軟件負載均衡算法。它能夠在客戶端配置服務端類別,而後輪詢請求以實現負載均衡。web

 當項目引入Eureka依賴後,會自動的引入ribbon的依賴,固然咱們能夠顯示的引入ribbon依賴。在集成Eureka時,DiscoveryEnabledNIWSServerList重寫了Ribbon的服務列表,在com.netflix.ribbon:ribbon-eureka:2.3.0模塊咱們能夠看到,同時使用 NIWSDiscoveryPing取代IPing:算法

file

1、Ribbo快速使用

 當前的實例咱們會涉及到Eureka註冊中心,兩個服務提供者(server-provider),一個服務消費者(server-consumer),首先,咱們啓動兩個服務提供者,並註冊到Eureka,服務提供接口以下:spring

@RestController
public class RibbonController {

    @RequestMapping("/sayHello")
    public String sayHello(String name) {
        return "hello!,"+name;
    }
}

 接下來,對以前文章的Eureka客戶端,即服務消費者進行相關改造,首先引入ribbon依賴(其實在引入eureka-client時就已經默認引入了Ribbon):segmentfault

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

 並對服務消費者代碼進行改造,將DiscoveryClient改成LoadBalancerClient,顧名思義,改爲支持負載均衡的客戶端,同時在消費者的主類上添加@EnableDiscoveryClient註解,開啓發現服務功能:瀏覽器

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class RibbonController {

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @Autowired
    private LoadBalancerClient client;

    @Autowired
    RestTemplate restTemplate;

    @GetMapping("/sayHello")
    public String sayHello(String name) {
        ServiceInstance instance = client.choose("server-provider");
        String res =  restTemplate.
            getForObject(instance.getUri().toString() 
                         + "sayHello?name=" + name, String.class);
        return res + " from :" + instance.getPort();
    }
}

 前後啓動Eureka註冊中心,啓動兩個服務提供者和一個服務消費者,在Eureka的監控頁面咱們能夠看到以下的內容:服務器

file

接下來用瀏覽器請求服務調用者的接口獲得的結果是:架構

hello!,test from :9001 

 hello!,test from :9002

 響應爲9001和9002交替的出現,這代表Ribbon客戶端正在用輪詢的方式實現了負載均衡。app

 固然咱們還可使用一種更爲簡單的方法,修改客戶端的調用代碼,給RestTemplate添加 @LoadBalanced註解,經過restTemplate直接使用URL :http://server-provider/sayHel...,這裏的server-provider是服務提供者的註冊在Eureka的服務名稱, @LoadBalanced的默認算法是輪詢:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class RibbonController {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @Autowired
    RestTemplate restTemplate;

    @GetMapping("/sayHello")
    public String sayHello(String name) {
        String res = restTemplate
            .getForObject("http://server-provider/sayHello?name=" + name, String.class);
        return res;
    }

 經過這樣簡潔的方式一樣能夠實現負載均衡的調用。

二 、Ribbon進階配置

 上文簡單的展現了Ribbon的基本功能,可是Ribbon還能夠有更多自定義的配置,好比咱們想修改默認的負載均衡算法、自定義HTTP線程池等,咱們該如何實現呢?

2.1 Ribbon的核心組件

 在ribbon-loadbalancer項目中,定義和不少的接口,其中就有

  • IRule:輪詢的策略的接口。
  • ServerList:定義用於獲取服務器列表的額方法的接口。
  • IPing:定義了以什麼方式去檢查服務之間是否通信良好的接口。
  • file

2.2 實現自定義算法

 Spring Cloud提供了爲Ribbon的默認實現,固然咱們也能夠自定義的去修改輪詢策略等配置,首選咱們在客戶端你的啓動類上添加@RibbonClient註解,

import com.microservice.RibbonConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;

@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
@RibbonClient(name = "server-provider",configuration = RibbonConfig.class)
public class ServerConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServerConsumerApplication.class, args);
    }
}

 @RibbonClient(name = "server-provider",= RibbonConfig.class)

  • name:是服務提供者註冊在Eureka的名稱;
  • configuration :是咱們即將自定義的配置類;

接下來,咱們新建RibbonConfig配置類,

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 配置Ribbon
 */
@Configuration
public class RibbonConfig {

    /**
     * 使用隨機的輪詢方法
     *
     * @return
     */
    @Bean
    public IRule iRule() {
        return new RandomRule();
    }

}

注意:確保RibbonConfig所在的包不能被@ComponentScan掃描到,若是主類使用@SpringBootApplication,也須要避免會被自動掃描,具體的配置以下:

file

 服務調用的代碼不變化:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class RibbonController {


    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @Autowired
    RestTemplate restTemplate;


    @GetMapping("/sayHello")
    public String sayHello(String name) {
        String res = restTemplate.getForObject("http://server-provider/sayHello?name=" + name, String.class);
        return res;
    }

 咱們使用瀏覽器調用接口 http://192.168.1.103:5168/sayHello?name=test,返回的結果是以隨機的方式返回的;

2.3 @RibbonClient註解

 咱們經過指定@RibbonClient中configuration的配置能夠修改默認的實現,針對IRule的實現,SpringCloud有如下的實現:

  • RoundRobinRule:輪詢,默認的每一次的請求都是輪流分配給服務提供者;
  • AvailabilityFilteringRule:更具可用性進行過濾的策略。默認狀況下,若是RestClient最後三次鏈接失敗,則實例會電路跳閘,一旦實例跳閘,它將保持這個狀態30s,以後會被再次啓用;若是在連續鏈接失敗,則再會變成電路跳閘,等待的時間會指數級增加;
  • WeightedResponseTimeRule:每一個服務器根據響應的時間給予權重,響應時間越長,權重越少;
  • RandomRule:隨機策略

 固然還有其餘的權重策略,有興趣的同窗能夠自行的研究源代碼。

Spring Cloud提供了@RibbonClients這樣的一個註解,咱們的客戶端不可能只會調用一個提供者,這樣的註解咱們能夠配置多個提供者。

3、總結

 本章介紹了Ribbon組件做爲一個客戶端的負載均衡器對微服務架構方面起到了很是大的做用,咱們對Ribbon有了一個深刻的理解,同時咱們也能夠自定義一些配置,我相信微服務的學習並非一件很難的事。

file

.以就是本期的分享,你還能夠關注公衆號: 程序員笑笑生,關注更多精彩內容!

file

file

SpringCloud基礎教程(一)-微服務與SpringCloud

SpringCloud基礎教程(二)-服務發現 Eureka

SpringCloud基礎教程(三)-Eureka進階

SpringCloud 基礎教程(四)-配置中心入門

SpringCloud基礎教程(五)-配置中心熱生效和高可用

SpringCloud 基礎教程(六)-負載均衡Ribbon

更多精彩內容,請期待...

本文由博客一文多發平臺 OpenWrite 發佈!
個人博客[蘭陵笑笑生] ( http://www.hao127.com.cn/),歡...
相關文章
相關標籤/搜索