⒈Ribbon是什么?
Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡工具。
Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。我们在配置文件中列出负载均衡所有的机器,Ribbon会自动的帮助我们基于某种规则(如简单轮询、随机连接等等)去连接这些机器。Ribbon客户端组件提供了一列完善的配置项(如连接超时、重试等等),我们也能很容易的使用Ribbon实现自定义的负载均衡算法。
⒉负载均衡?
负载均衡(Load Balance,简称LB),在微服务或分布式集群中经常用到的一种功能,就是将用户的请求以某种规则平摊到多个服务器上,从而达到系统的高可用。
常见的负载均衡有软件例如Nginx、LVS等等,硬件F5等等。
相应的在中间件,例如Dubbo和Spring Cloud中均给我们提供了负载均衡,Spring Cloud的负载均衡算法可以自定义。
集中式负载均衡:即在服务的消费方和提供方之间使用独立的负载均衡设施(可以是硬件,如F5。也可以是软件,如Nginx),由该设施负责把请求通过某种策略转发至服务的提供方。
进程内负载均衡:将负载均衡逻辑集成到服务消费方,由消费方从服务注册中心获取有那些服务地址可用,然后消费方从这些地址中选择一个合适的服务器。(Ribbon属于进程内负载均衡,它只是一个类库,集成于服务消费方进程,消费方通过它来获取到服务提供方的地址)
⒊示例
因为Ribbon集成于服务消费方,这里我只展示服务消费方部分代码,完整代码请结合https://www.cnblogs.com/fanqisoft/p/10357598.html自行勾画。
①添加pom依赖
1 <dependency> 2 <groupId>org.springframework.boot</groupId> 3 <artifactId>spring-boot-starter-web</artifactId> 4 </dependency> 5 <dependency> 6 <groupId>org.springframework.cloud</groupId> 7 <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> 8 </dependency> 9 <dependency> 10 <groupId>org.springframework.cloud</groupId> 11 <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> 12 </dependency>
②修改配置文件
1 server.port=8200 2 3 spring.application.name=user-consumer 4 5 #eureka.instance.prefer-ip-address 注册服务的时候使用服务的ip地址 6 eureka.instance.prefer-ip-address=true 7 8 eureka.client.service-url.defaultZone:http://localhost:8761/eureka/
③对访问Rest资源的Bean加上@LoadBalanced负载均衡注解
1 @Bean 2 @LoadBalanced //使用负载均衡机制 3 public RestOperations restTemplate(){ 4 return new RestTemplate(); 5 }
④主程序启动上添加@EnableDiscoveryClient注解开启Eureka服务发现(@EnableDiscoveryClient注解也可以)
1 package cn.coreqi; 2 3 import org.springframework.boot.SpringApplication; 4 import org.springframework.boot.autoconfigure.SpringBootApplication; 5 import org.springframework.cloud.client.loadbalancer.LoadBalanced; 6 import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 7 import org.springframework.context.annotation.Bean; 8 import org.springframework.web.client.RestOperations; 9 import org.springframework.web.client.RestTemplate; 10 11 @SpringBootApplication 12 @EnableDiscoveryClient //开启服务发现功能 13 public class SpringbootcloudserviceconsumerApplication { 14 15 public static void main(String[] args) { 16 SpringApplication.run(SpringbootcloudserviceconsumerApplication.class, args); 17 } 18 }
⑤在控制器中注入RestTemplate并调用远程服务
1 package cn.coreqi.controller; 2 3 import cn.coreqi.entities.User; 4 import org.springframework.beans.factory.annotation.Autowired; 5 import org.springframework.web.bind.annotation.GetMapping; 6 import org.springframework.web.bind.annotation.RestController; 7 import org.springframework.web.client.RestOperations; 8 9 @RestController 10 public class UserController { 11 @Autowired 12 private RestOperations restTemplate; 13 14 @GetMapping("/userno1") 15 public User getUsersFirst(){ 16 User[] users = restTemplate.getForObject("http://user-provider/users",User[].class); 17 return users[0]; 18 } 19 }
★Ribbon和Eureka整合后服务消费方可以直接调用服务而不用再关心提供服务的地址以及提供服务的端口号。
Ribbon其实就是一个软负载均衡的客户端软件,它可以和其它所需请求的客户端结合使用,和Eureka结合只是其中的一个实例。
⒋Ribbon核心组件IRule支持的负载均衡算法
名称 | 特点 |
RoundRobinRule | 轮询 |
RandomRule | 随机 |
AvailabilityFilteringRule |
会先过滤掉由于多次访问故障而处于断路器跳闸状态 和并发的连接数量超过阈值的服务,然后对剩余的服 务列表按照轮询策略进行访问。 |
WeightedResponseTimeRule |
根据平均响应时间计算所有服务的权重,响应时间越 快服务权重越大被选中的概率越高,刚启动时如果统 计信息不足,则使用RoundRobinRule(轮询)策略 ,等到统计信息足够,则会自动切换回WeightedRe -sponseTimeRule |
RetryRule |
先按照RoundRobinRule的策略获取服务,如果获取 服务失败,则在指定时间内会进行重试,获取可用的 服务。 |
BestAvailableRule |
会过滤掉由于多次访问故障而处于断路器跳闸状态的 服务,然后选择一个并发量最小的服务。 |
ZoneAvoidanceRule |
默认规则,复合判断Server所在区域的性能和Server 的可用性选择服务器。 |
⒌SpringCloud如何更改默认的负载均衡算法?
1 package cn.coreqi.config; 2 3 import com.netflix.loadbalancer.IRule; 4 import com.netflix.loadbalancer.RandomRule; 5 import org.springframework.context.annotation.Bean; 6 import org.springframework.context.annotation.Configuration; 7 8 @Configuration 9 public class RibbonConfig { 10 @Bean 11 public IRule myRule(){ 12 return new RandomRule(); 13 } 14 }
⒍SpringCloud如何自定义Ribbon
①添加配置均衡算法的配置类
★这个自定义配置类不能放在@ComponentScan所扫描的当前包及其子包下,否则这个自定义配置类会被所有的Ribbon客户端所共享,也就达不到特殊化定制的目的了。
1 package myrule; 2 3 import com.netflix.loadbalancer.IRule; 4 import org.springframework.context.annotation.Bean; 5 import org.springframework.context.annotation.Configuration; 6 7 @Configuration 8 public class RibbonConfig { 9 @Bean 10 public IRule myRule(){ 11 return new MyRandomRule(); 12 } 13 }
②在主程序启动类上添加@RibbonClient注解,并指定其name及configuration属性。从而在启动该微服务的时候就能去加载我们自定义的Ribbon配置类,使配置生效。
1 package cn.coreqi; 2 3 import myrule.RibbonConfig; 4 import org.springframework.boot.SpringApplication; 5 import org.springframework.boot.autoconfigure.SpringBootApplication; 6 import org.springframework.cloud.client.loadbalancer.LoadBalanced; 7 import org.springframework.cloud.netflix.ribbon.RibbonClient; 8 import org.springframework.context.annotation.Bean; 9 import org.springframework.web.client.RestOperations; 10 import org.springframework.web.client.RestTemplate; 11 12 @SpringBootApplication 13 @EnableDiscoveryClient //开启服务发现功能 14 @RibbonClient(name = "USER-PROVIDER",configuration = RibbonConfig.class) 15 public class SpringbootcloudserviceconsumerApplication { 16 17 public static void main(String[] args) { 18 SpringApplication.run(SpringbootcloudserviceconsumerApplication.class, args); 19 } 20 }
③新建自定义负载均衡算法类并继承AbstractLoadBalancerRule重写choose方法
1 package myrule; 2 3 import com.netflix.client.config.IClientConfig; 4 import com.netflix.loadbalancer.AbstractLoadBalancerRule; 5 import com.netflix.loadbalancer.Server; 6 7 public class MyRandomRule extends AbstractLoadBalancerRule { 8 @Override 9 public void initWithNiwsConfig(IClientConfig iClientConfig) { 10 11 } 12 13 @Override 14 public Server choose(Object o) { 15 return null; 16 } 17 }