Spring Cloud 自定义Eureka Ribbon负载均衡策略

2020-05-25 00:00:00 服务 配置 自定义 策略 负载均衡

在上一篇文章

null:Spring Cloud 服务注册与发现 Eurekazhuanlan.zhihu.com

中,我们使用Eureka的负载均衡策略解决了服务消费者在调用服务提供者接口时把提供者的地址硬编码在消费者代码里的问题,同时实现了简单的负载均衡,接口会返回hello world,this is spring-boot-providerhello world,this is spring-boot-provider-v2。但是我们使用的是Eureka默认的负载均衡策略。

在微服务架构中,业务会被拆分成一个个彼此独立的服务,服务间的通讯基于http restful。

Spring Cloud有两种服务间调用的方式,RibbonFeign。下面我们简单介绍下Ribbon。

0. 开发环境

  • IDE:IntelliJ IDEA 2017.1 x64
  • jdk:1.8.0_91
  • Spring Boot:2.0.9.RELEASE
  • Spring Cloud:Finchley.RELEASE

1. Ribbon简介

Spring Cloud Ribbon 是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现。通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用。Spring Cloud Ribbon虽然只是一个工具类框架,但它不像服务注册中心、配置中心、API网关那样需要独立部署。它几乎存在于每一个Spring Cloud构建的微服务和基础设施中。微服务间的调用、API网关的请求转发等内容,实际上都是通过Ribbon来实现的。包括Spring Cloud的另一种服务调用方式Feign,也是基于Ribbon实现的。

2. Ribbon负载均衡策略

Ribbon的核心组件是IRule,IRule是所有负载均衡策略的父接口,其子类有:

每一个子类就是一种负载均衡策略

  • RandomRule:随机选取负载均衡策略,随机Random对象,在所有服务实例中随机找一个服务的索引号,然后从上线的服务中获取对应的服务。
  • RoundRobinRule:线性轮询负载均衡策略。
  • WeightedResponseTimeRule:响应时间作为选取权重的负载均衡策略,根据平均响应时间计算所有服务的权重,响应时间越短的服务权重越大,被选中的概率越高。刚启动时,如果统计信息不足,则使用线性轮询策略,等信息足够时,再切换到WeightedResponseTimeRule。
  • RetryRule:使用线性轮询策略获取服务,如果获取失败则在指定时间内重试,重新获取可用服务。
  • ClientConfigEnabledRoundRobinRule:默认通过线性轮询策略选取服务。通过继承该类,并且对choose方法进行重写,可以实现更多的策略,继承后保底使用RoundRobinRule策略。
  • BestAvailableRule:继承自ClientConfigEnabledRoundRobinRule。从所有没有断开的服务中,选取到目前为止请求数量小的服务。
  • PredicateBasedRule:抽象类,提供一个choose方法的模板,通过调用AbstractServerPredicate实现类的过滤方法来过滤出目标的服务,再通过轮询方法选出一个服务。
  • AvailabilityFilteringRule:按可用性进行过滤服务的负载均衡策略,会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,还有并发的连接数超过阈值的服务,然后对剩余的服务列表进行线性轮询。
  • ZoneAvoidanceRule:本身没有重写choose方法,用的还是抽象父类PredicateBasedRule的choose。

2. 自定义负载均衡策略

上篇文章中我们使用Ribbon实现负载均衡,使用的是Ribbon默认的负载均衡策略,接下来我们自定义负载均衡策略。

2.1 代码自定义策略

代码自定义负载均衡策略需要注意,要避免Spring Boot的包扫描,自定义的规则必须在Eureka的规则实例化以后再实例化才会生效。

2.1.1 新建负载均衡策略配置类

我们直接在上篇文章的spring-boot-consumer服务上进行修改

在启动类SpringBootConsumerApplication的上层新建config包,然后新建LoadBalanced类。使用LoadBalanced类注册一个新的IRule来替换Eureka。

package cn.wbnull.config;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.WeightedResponseTimeRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class LoadBalanced {

    @Bean
    public IRule iRule() {
        return new WeightedResponseTimeRule();
        //return new RandomRule();
    }
}

相关文章