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