Ribbon實現客戶端負載均衡

  • 2019 年 10 月 6 日
  • 筆記

什麼是Ribbon?

客戶端負載均衡組件。

前期準備:

搭建一個Eureka集群和一個註冊服務

https://www.cnblogs.com/noneplus/p/11374883.html

  • 創建服務提供者msc-provider-5002,msc-provider-5003
  • 創建消費者msc-consumer-80

pom依賴

服務提供者msc-provider-5001,msc-provider-5002,msc-provider-5003:

<parent>          <groupId>org.springframework.boot</groupId>          <artifactId>spring-boot-starter-parent</artifactId>          <version>2.1.7.RELEASE</version>          <relativePath/> <!-- lookup parent from repository -->      </parent>        <properties>          <java.version>1.8</java.version>          <spring-cloud.version>Greenwich.SR2</spring-cloud.version>      </properties>        <dependencies>          <dependency>              <groupId>org.springframework.cloud</groupId>              <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>          </dependency>          <dependency>              <groupId>org.springframework.boot</groupId>              <artifactId>spring-boot-starter-test</artifactId>              <scope>test</scope>          </dependency>            <dependency>              <groupId>org.springframework.cloud</groupId>              <artifactId>spring-cloud-starter-config</artifactId>          </dependency>  <!--        Eureka客戶端啟動需要依賴web模塊-->          <dependency>              <groupId>org.springframework.boot</groupId>              <artifactId>spring-boot-starter-web</artifactId>          </dependency>            <dependency>              <groupId>org.springframework.cloud</groupId>              <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>          </dependency>      </dependencies>        <dependencyManagement>          <dependencies>              <dependency>                  <groupId>org.springframework.cloud</groupId>                  <artifactId>spring-cloud-dependencies</artifactId>                  <version>${spring-cloud.version}</version>                  <type>pom</type>                  <scope>import</scope>              </dependency>          </dependencies>      </dependencyManagement>        <build>          <plugins>              <plugin>                  <groupId>org.springframework.boot</groupId>                  <artifactId>spring-boot-maven-plugin</artifactId>              </plugin>          </plugins>      </build>

消費者msc-consumer-80:

<parent>      <groupId>org.springframework.boot</groupId>      <artifactId>spring-boot-starter-parent</artifactId>      <version>2.1.7.RELEASE</version>      <relativePath/> <!-- lookup parent from repository -->  </parent>    <properties>      <java.version>1.8</java.version>      <spring-cloud.version>Greenwich.SR2</spring-cloud.version>  </properties>    <dependencies>      <dependency>          <groupId>org.springframework.cloud</groupId>          <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>      </dependency>      <dependency>          <groupId>org.springframework.boot</groupId>          <artifactId>spring-boot-starter-test</artifactId>          <scope>test</scope>      </dependency>        <dependency>          <groupId>org.springframework.cloud</groupId>          <artifactId>spring-cloud-starter-config</artifactId>      </dependency>      <!--        Eureka客戶端啟動需要依賴web模塊-->      <dependency>          <groupId>org.springframework.boot</groupId>          <artifactId>spring-boot-starter-web</artifactId>      </dependency>        <dependency>          <groupId>org.springframework.cloud</groupId>          <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>      </dependency>  </dependencies>    <dependencyManagement>      <dependencies>          <dependency>              <groupId>org.springframework.cloud</groupId>              <artifactId>spring-cloud-dependencies</artifactId>              <version>${spring-cloud.version}</version>              <type>pom</type>              <scope>import</scope>          </dependency>      </dependencies>  </dependencyManagement>    <build>      <plugins>          <plugin>              <groupId>org.springframework.boot</groupId>              <artifactId>spring-boot-maven-plugin</artifactId>          </plugin>      </plugins>  </build>

服務提供者5001配置

  • 主啟動類:(提供者並不需要進行註解配置)
  • TestController(測試負載均衡)
package zkrun.top.controller;    import org.springframework.web.bind.annotation.*;    @RestController  public class TestController {        @GetMapping(value = "/info/get")      public String response()      {          return "msc_provider_5001";      }      }
  • application.yaml(基本無修改,對比Eureka配置)
server:    port: 5001  spring:    application:      name: msc-provider  #應用名稱  eureka:    client:      service-url:        defaultZone: http://eureka6001.com:6001/eureka/,http://eureka6002.com:6002/eureka/,http://eureka6003.com:6003/eureka/    instance:      instance-id: msc-provider-5001      prefer-ip-address: true     #訪問路徑可以顯示IP地址

複製5001的代碼到5002和5003

  • 主啟動類(修改類名)
  • TestController(修改返回值)
  • application.yaml(修改端口和instance-id)

大致的效果就是訪問不同的端口,有不同的返回值:

消費者msc-consumer-80配置

  • RibbonConfig
package zkrun.top.config;    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 RibbonConfig {            @Bean          @LoadBalanced          public RestTemplate getRestTemplate()          {              return new RestTemplate();          }  }
  • Controller_Consumer
package zkrun.top.controller;      import org.springframework.beans.factory.annotation.Autowired;  import org.springframework.web.bind.annotation.RequestMapping;  import org.springframework.web.bind.annotation.RestController;  import org.springframework.web.client.RestTemplate;    @RestController  public class Controller_Consumer {        private static final String REST_URL_PREFIX = "http://MSC-PROVIDER";        @Autowired      private RestTemplate restTemplate;        @RequestMapping(value = "/consumer/info/get")      public String request()      {          return restTemplate.getForObject(REST_URL_PREFIX + "/info/get", String.class);      }          }
  • yaml
server:    port: 80    eureka:    client:      register-with-eureka: false      service-url:        defaultZone: http://eureka6001.com:6001/eureka/,http://eureka6002.com:6002/eureka/,http://eureka6003.com:6003/eureka/
  • 主類(@RibbonClient(name="MSC_PROVIDER"))
package zkrun.top;      import org.springframework.boot.SpringApplication;  import org.springframework.boot.autoconfigure.SpringBootApplication;  import org.springframework.cloud.netflix.eureka.EnableEurekaClient;  import org.springframework.cloud.netflix.ribbon.RibbonClient;    @SpringBootApplication  @EnableEurekaClient  @RibbonClient(name="MSC_PROVIDER")  public class App_msc_consumer_80  {      public static void main(String[] args)      {          SpringApplication.run(App_msc_consumer_80.class, args);      }  }

運行測試:

啟動Eureka6001,6002,6003

啟動Provider5001,5002,5003

啟動Consumer80

訪問:

http://localhost/consumer/info/get

點擊刷新就會有輪詢效果:

負載均衡算法切換

在RibbonConfig下添加

@Bean  public IRule myRule()  {          return new RandomRule();// Ribbon默認是輪詢,自定義為隨機          //return new RoundRobinRule();// Ribbon默認是輪詢  }

支持的算法:


代碼參考:https://github.com/HCJ-shadow/Ribbon