负载均衡 LoadBalancer

负载均衡

负载均衡一般分为服务端负载均衡客户端负载均衡

  • 服务端负载均衡:

指在服务器端进行负载均衡的策略。在这种策略下,负载均衡器位于服务器端(如 Nginx),当客户端发起服务调用时,根据服务器的负载情况,将请求分发到不同的服务器上,以实现请求的均衡分配。

负载均衡器可以根据特定的算法(如轮询、权重等)来选择合适的服务器。这种方式可以有效地提高系统的可用性和扩展性,但也会增加服务器端的压力。

  • 客户端负载均衡:

指在客户端进行负载均衡的策略。在这种策略下,负载均衡器位于客户端(如Loadbalancer、Ribbon),每个发起服务调用的客户端都有完整的目标服务地址列表,根据配置的负载均衡策略(如随机选择、加权轮询等),由客户端自己决定向哪台服务器发起调用。

客户端负载均衡可以减轻服务器端的压力,提高系统的性能和吞吐量。然而,客户端负载均衡依赖于客户端的实现,需要对客户端进行相应的配置和管理。

Ribbon

Spring Cloud Ribbon 是 NetFlix 开源的一个基于 HTTP 和 TCP 的客户端负载均衡器。

Ribbon 可以和 Eureka、Consul 等服务发现组件集成,通过向服务注册中心查询可用的服务列表,并通过一定的负载均衡算法(如轮训、随机等)选择目标服务实例。

Ribbon 已经进入维护模式,并且 Ribbon 2 并不与 Ribbon 1 相互兼容;

Ribbon 负载均衡策略有以下七种

  • 轮询(RoundRobinRule)

按照一定的顺序依次调用服务实例。例如有 ServerA、ServerB、ServerC 3个服务,按照 ABC 顺序依次调用服务。(按部就班)

默认超过 10 次获取到的 Server 都不可用,会返回一个空的 Server。

  • 权重(WeightedResponseTimeRule)

根据每个服务提供者的响应时间分配一个权重,响应时间越长,权重越小,被选中的可能性也就越低。(能者多劳)

实现原理:刚开始使用轮询策略则开启一个计时器,每一段时间收集一次所有服务提供者的平均响应时间,然后再给每个服务提供者附上一个权重,权重越高的服务被选中的概率也就越大。

  • 随机(RandomRule)

从服务提供者列表随机选择一个服务实例调用。(随性而为)

如果随机到的 Server 为 null 或者不可用的话,会 while 不停的循环选取。

  • 最小连接数(BestAvailableRule)

也称为最小并发数策略,首先遍历服务提供者列表,然后选择连接数最小的一个服务实例 。如果有相同的最小连接数,那么会调用轮询策略进行选取。(让最闲的来)

此策略会过滤掉故障服务,基于过去30分钟的统计结果选取当前并发量最小的服务节点,即最“闲”的节点作为目标地址。

  • 重试(RetryRule)

按照轮询策略来获取服务,如果获取的服务实例为 null 或已经失效,则在指定时间内不断地进行重试来获取服务,如果超过指定时间依然没有获取到服务实例,则返回 null。(卷土重来)

  • 可用性敏感(AvailabilityFilteringRule)

扩展了轮询策略,会先通过默认的轮询选取一个 Server,再去判断该 Server 是否超时可用,当前连接数是否超限,都成功再返回。

  • 区域敏感(ZoneAvoidanceRule)——默认策略

扩展了轮询策略,除了过滤超时和链接数过多的 Server,还会过滤掉不符合要求的 Zone 区域里面的所有节点, 在一个区域/机房内的服务实例中轮询。先过滤再轮询

修改 Ribbon 默认负载均衡策略方法如下:

在 application.yaml 配置文件中加入以下配置:

# 针对的被调用方微服务名称,不加就是全局生效
cloud-provider-8001:
  ribbon:
    # 设置为 最小连接数策略
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.BestAvailableRule
LoadBalancer

Spring Cloud LoadBalancer 是 Spring Cloud 团队在 Spring Cloud 2020 版本后引入的一个新的负载均衡组件。

LoadBalancer 提供了一个抽象的负载均衡接口,可以与多种负载均衡实现(如 Ribbon、Nacos、Consul等)进行匹配。

LoadBalancer 提供了两种负载均衡策略:

  • 轮询(RoundRobinLoadBalancer)
  • 随机(RandomLoadBalancer)

LoadBalancer 默认策略为轮询。

修改 LoadBalancer 默认负载均衡策略方法如下:

首先创建随机策略的配置类 LoadBalancerConfig,具体如下:

public class LoadBalancerConfig {
    /**
     * 将官方提供的 RandomLoadBalancer 注册为 Bean
     */
    @Bean
    public ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
    }
}

然后使用 @LoadBalancerClient 注解配置对应服务的负载均衡策略,具体如下:

@Configuration
@LoadBalancerClient(value = "cloud-provider-8001", configuration = LoadBalancerConfig.class)
public class BeanConfig {
    @Bean
    // 负载均衡
    @LoadBalanced
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}

@LoadBalancerClient 注解也可以加在启动类上方,name 属性为调用的微服务的名称,configuration 属性为上面我们定义的随机负载均衡策略类。

我们可以通过以下方法进行验证负载均衡策略是否发生了改变,首先新建一个 provider-8002 模块,除了端口号不同之外,其他都一样。然后分别在 provider-8001 和 provider-8002 的控制类中加入如下接口:

@Value("${server.port}")
private String port;

@GetMapping("/get/port")
public String getPort() {
    return port;
}

然后在 openfeign-consumer80 模块中的 IOpenFeignService 接口服务中加入对应接口,调用远端服务。分别启动 provider-8001 和 provider-8002,这时在 Eureka 界面可以看到 cloud-provider-8001 有两个实例。

使用 Postman 调用接口,查看返回的端口号,可以发现,没有加上面配置之前,效果为 8001 和 8002 交替出现,加了之后,则为随机出现,如果觉得效果不太明显,可以多加两个 provider-8003、provider-8004。

你可能感兴趣的:(SpringCloud,负载均衡,loadbalancer,springcloud)