SpringCloud Ribbon 负载均衡
Spring Cloud Ribbon 是一个基于 HTTP 和 TCP 的客户端负载均衡工具。可以将面向服务的 REST 模板请求自动转化成客户端负载均衡的服务调用。Spring Cloud Ribbon 虽然是一个工具类框架,但它不像服务注册中心、配置中心、API网关那样需要独立部署。但是它几乎存在于每一个 Spring Cloud 构建的微服务和基础设置中。因为微服务间的调用,API 网关的请求转发等内容,实际上都是通过 Ribbon 来实现的,包括 Feign 它也是基于 Ribbon 实现的工具。所以 Spring Cloud Ribbon 的理解和使用,对于我们使用 Spring Cloud 来构建微服务非常重要。
一、概述
【1】是什么:Spring Cloud Ribbon 是基于 Netflix Ribbon实现的一套客户端的负载均衡的工具。简单的说,Ribbon是 Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将 Netflix 的中间层服务连接在一起。Ribbon 客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说就是在配置文件中列出 Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮你基于某种规则(如单轮询,随机连接等)去连接这些机器。我们也很容易使用 Ribbon实现自定义的负载均衡算法。
【2】作用:LB,即负载平衡(Load Balance)在微服务或分布式集群中经常用的一种应用。负载平衡简单的说,就是将用户的请求平摊的分配到多个服务,而达到服务的HA(高可用)。常见的负载均衡软件Nginx,LVS,硬件F5等。相应的中间件,例如:Dubbo 和 SpringCloud 中均给我们提供了负载均衡,SpinrgCloud 的负载均衡算法可以自定义。
【3】主要分为两种:1)、集中式LB:偏硬件,即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件F5,也可以是软件Nginx),由该设置负责把访问请求通过某种策略转发至服务的提供方; 2)、进程内LB:将 LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。
Ribbon 就属于进程内 LB,它只是一个库,集成于消费方进程,消费方通过它来获取到服务提供方的地址。
二、Ribbon 初步配置
【1】修改客户端,例如:microservicecloud-consumer-dept-80 工程的 pom.xml 文件;
【2】修改 application.yml,追加 eureka 的服务注册地址;
【3】对 ConfigBean 配置类,添加新注解 @LoadBalance 获得 RestTemplate 时,加入 Ribbon 的配置;
【4】主启动类 DeptConsumer80_App 添加 @EnableEurekaClient;
【5】修改 deptController_Consumer 客户端访问类;
三、Ribbon 负载均衡
四、Ribbon 核心组件 IRule
Irule:根据特定算法从服务中选取一个要访问的服务。
【1】RoundRobinRule:轮询;
【2】RandomRule:随机;
【3】AvaliabilityFilteringRule:会先过滤掉由于多次访问故障而处于熔断器跳闸状态的服务,还有并发的连接数量超过阈值的服务,然后对剩余的服务列表按照轮询策略进行访问;
【4】WeightedResponseTimeRule:根据平均响应时间计算所有服务的权重,响应时间越快权重越大被选中的概率就越高,刚启动时统计信息不足时,则使用 RoundRobinRule 策略,等统计信息足够,则会切换到 WeightedResponseTimeRule;
【5】RetryRule:先按照 roundRobinRule 的策略获取服务,如果获取失败则会在指定时间内进行重试,获取可用服务;
【6】BestAvailableRule:会过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务;
【7】ZoneAvoidanceRule:默认规则,复合判断 server 所在区域的性能和 server 的可用性选择器;
以上算法要使用则需要在 customer 端得 configBean.java 配置文件中添加(重要):
五、Ribbon 自定义
【1】修改 microservicecloud-consumer-dept-80;
【2】主启动类添加注解 @RibbonClient:在启动该微服务的时候就能去加载我们的自定义 Ribbon 配置类,从而使配置生效,如:@RibbonClient(name = "MICROSERVICECLOUD-DEPT",configuration=MySelfRule.class)
1 @RibbonClient(name="MICROSERVICECLOUD-DEPT",configuration=MySelfRule.class) 2 public class DeptConsumer80_App 3 {
【3】警告:这个配置类不能放在 @ComponentScan(主启动Java文件的包下面)所扫描的当前包以及子包下,否则我们自定义的这个配置类就会被所有的 Ribbon 客户端共享,也就是说我们达不到特殊化定制的目的。自定义 myrule:(不能和主启动类同一个 package)。不同之处就在于这个类不会扫描到,而是通过 @RibbonClient 注解将其与固定的服务进行绑定。达到与其他微服务不一样的负载均衡算法的目的。
1 @Configuration 2 public class MySelfRule 3 { 4 @Bean 5 public IRule myRule() 6 { 7 //return new RandomRule();// Ribbon默认是轮询,我自定义为随机 8 //return new RoundRobinRule();// Ribbon默认是轮询,我自定义为随机 9 return new RandomRule_ZY();// 我自定义为每台机器5次 10 } 11 }
【4】深度解析:问题:依旧是轮询策略,但是新需求,每个服务器要求被调用5次。即以前是每台机器一次,现在5次。对随机算法源码进行了修改。继承 AbstractLoadBalancerRule 实现负载均衡算法。详细学习,可以参考 GitHub 上 Ribbon 源码。