SpringCloud五大神兽之Ribbon--负载均衡(一)

 

一、什么是Ribbon

springcloud Ribbon 是基于Netflix Ribbon实现的一套客户端负载均衡的工具,主要功能是提供客户端的软件负载均衡算法。springcloud 的负载均衡(Load Balace 简称LB)算法可以自定义。这就类似于我们平时逛超市结账一样,消费者(客户端)肯定会去选择排队人数最少的结账队列去结账,而这就被称为客户端的负载均衡。

负载均衡大致可分为两大类:集中式负载均衡、进程内负载均衡。而本文中的Ribbon就属于进程内的LB。

Ribbon与Eurea整合后,客户端能够直接通过微服务名称调用服务,而不用在关心地址和端口。

二、Ribbon默认的七种负载均衡算法

  1. RoundRobinRule:简单轮询负载均衡,采用的是计数器count,i++的方式,循环访问下一个server。
  2. RandomRule:随机负载均衡,随机选择一个server。
  3. RetryRule:重试功能负载均衡。
  4. AvailabilityFilteringRule:过滤失败连接式负载均衡。
  5. WeightedResponeTimeRule:加权响应时间式负载均衡,每次访问后给出权值,响应时间越短,权值越大,反之越小。
  6. BestAvailableRule:选择一个最小的并发负载均衡。
  7. ZoneAvoidanceRule:区域感知轮询负载均衡。

三、springcloud中eureka与ribbon的整合

1、在客户端(消费者)微服务的pom文件中引入依赖

1<!-- Ribbon相关 --> 2 <dependency> 3 <groupId>org.springframework.cloud</groupId><!-- 表示是eureka的客户端,或者叫提供端 --> 4 <artifactId>spring-cloud-starter-eureka</artifactId> 5 </dependency> 6 <dependency> 7 <groupId>org.springframework.cloud</groupId> 8 <artifactId>spring-cloud-starter-ribbon</artifactId> 9 </dependency> 10 <dependency> 11 <groupId>org.springframework.cloud</groupId> 12 <artifactId>spring-cloud-starter-config</artifactId> 13 </dependency> 14

2、修改application.yml,追加eureka的服务注册地址

1server: 2 port: 80 3 4#providerUrl: 'http://localhost:8001' 5providerUrl: 'http://microservicecloud-dept' #可以根据微服务名称访问微服务,不再需要ip地址和端口号,提高安全性 6 7#与eureka服务端配置的地址一致,表示将要入驻到的地址,可以配置多个 8eureka: 9 client: 10 register-with-eureka: false #并不将自己注册到微服务注册中心 11 service-url: 12 defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ 13 14

3、在java配置类中,将RestTemplate上加注解:@LoadBalanced,表示开启自动负载均衡规则。

1package com.atguigu.springcloud.cfgbeans; 2 3import com.netflix.loadbalancer.IRule; 4import com.netflix.loadbalancer.RandomRule; 5import com.netflix.loadbalancer.RetryRule; 6import com.netflix.loadbalancer.RoundRobinRule; 7import org.springframework.cloud.client.loadbalancer.LoadBalanced; 8import org.springframework.context.annotation.Bean; 9import org.springframework.context.annotation.Configuration; 10import org.springframework.web.client.RestTemplate; 11 12/** 13 * Created with IntelliJ IDEA. 14 * Description: 15 * User: 16 * Date: 2019-04-08 17 * Time: 21:34 18 */ 19@Configuration 20public class ConfigBean { 21 @Bean 22 @LoadBalanced //开启自动负载均衡,即可以通过微服务名称进行调用微服务,不需要使用ip+端口号进行调用了。 23 public RestTemplate getRestTemplate() { 24 return new RestTemplate(); 25 } 26 27 28 /** 29 * springcloud的Riboon已经配置了七种负载均衡的算法,它们之间可以相互切换。 30 * 这七种负载均衡算法都是 IRule 接口的实现类 31 * @return 32 */ 33 @Bean 34 public IRule getIRule() { 35 return new RoundRobinRule();//简单轮询负载均衡,若没有配置该Bean,则Ribbon默认采取该种方式的负载均衡 36// return new RandomRule();//随机负载均衡 37// return new RetryRule();//重试轮询负载均衡 38 } 39} 40 41

springcloud有其中默认的负载均衡算法,它们之间可以相互切换。如上代码所示,只需要在Java Bean配置类中注入接口 IRule的实现类即可。

当需要某种负载均衡时,就 return new 某一个就行了。若没有配置该bean,则默认采用**RoundRobinRule()**轮询负载均衡的方式。这七个已配置好的负载均衡算法都是 IRule 接口的实现类。

4.自定义Ribbon的负载均衡策略

需要在主启动类上添加 @EnableEurekaClient  以及  @RibbonClien。

1package com.atguigu.springcloud; 2 3import com.atguigu.mySeltRibbonRule.MySelfRule; 4import org.springframework.boot.SpringApplication; 5import org.springframework.boot.autoconfigure.SpringBootApplication; 6import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 7import org.springframework.cloud.netflix.ribbon.RibbonClient; 8 9/** 10 * Created with IntelliJ IDEA. 11 * Description: 12 * User: 13 * Date: 2019-04-08 14 * Time: 22:18 15 */ 16@SpringBootApplication 17@EnableEurekaClient 18//在消费端(客户端)的启动类上添加@RibbonClient注解,即可在启动的时候去加载自定义的Ribbon配置类,从而使配置生效 19//name--表示针对于某一个微服务,填的是微服务的名称 20//configuration--表示的自定义的配置文件 21@RibbonClient(name = "microservicecloud-dept",configuration = MySelfRule.class) 22public class DeptConsumer_80 { 23 public static void main(String[] args) { 24 SpringApplication.run(DeptConsumer_80.class,args); 25 } 26} 27 28

需要注意的配置细节--官方文档明确提出的警告:

              这个自定义配置类不能放在@ComponentScan所扫描的当前包下以及其子包下。否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,达不到特殊化定制的效果和目的了。

**           即:这个配置类不能放在含有主启动类的包下,因为**@SpringBootApplication是一个复合型注解,包含了@ComponentScan注解。

**          此时应该新建一个包,与主启动类所在包同级的一个包。**

MySelfRule类:

 

1package com.atguigu.mySeltRibbonRule; 2 3import com.netflix.loadbalancer.IRule; 4import com.netflix.loadbalancer.RandomRule; 5import org.springframework.context.annotation.Bean; 6import org.springframework.context.annotation.Configuration; 7 8/** 9 * @Author: 10 * @Despriction: 自定义Ribbon负载均衡配置类 11 * @Package: com.atguigu.mySeltRibbonRule 12 * @Date:Created in 2019/4/28 15:38 13 * @Modify By: 14 */ 15@Configuration 16public class MySelfRule { 17 @Bean 18 public IRule getIRule() { 19// return new RoundRobinRule();//简单轮询负载均衡,若没有配置该Bean,则Ribbon默认采取该种方式的负载均衡 20 return new RandomRule();//随机负载均衡 21// return new RetryRule();//重试轮询负载均衡 22 } 23 24} 25 26

注:若需要返回一个我们自定义的负载均衡算法,即 return new MySelfRibbonRule();

  • 在MySelfRule类同一个包下新建一个MySelfRibbonRule类。
  • MySelfRibbonRule 继承 AbstractLoadBalancerRule 抽象类,因为该类实现了 IRule 接口。
  • 将随机轮询类 RandomRule里的方法复制进来,根据自己的逻辑需求在方法——

public Server choose(ILoadBalancer lb,Object key) {.......}进行修改。

代码交流 2021