欢迎光临
我们一直在努力

Ribbon&LoadBalancer负载均衡原理

一、负载均衡介绍

负载均衡(Load Balance)是指将负载(工作任务)进行平衡、分摊到多个操作单元上运行,例如 FTP 服务器、Web 服务器、企业核心应用服务器等,从而协同完成工作任务,提高系统的可用性、性能和可扩展性。

思考:
如果有多个 Provider 实例,Consumer 应该如何调用?

目前主流的负载均衡方案分为以下两种:

  • 集中式负载均衡:在消费者和服务提供方中间使用独立的代理进行负载。可以是硬件(如 F5),也可以是软件(如 Nginx)。
  • 客户端负载均衡:由客户端根据自身请求情况实现负载均衡,例如 Ribbon。

二、客户端负载均衡 vs 服务端负载均衡

1. 客户端负载均衡

例如 Spring Cloud 中的 Ribbon。客户端维护一个服务器地址列表,在发送请求前通过负载均衡算法选择一个服务器进行访问。
特点:在客户端进行负载均衡算法的分配。

在这里插入图片描述

2. 服务端负载均衡

例如 Nginx。客户端发送请求到负载均衡器,由负载均衡器通过算法选择一台服务器进行转发。
特点:在服务器端进行负载均衡算法的分配。

在这里插入图片描述


三、常见负载均衡算法

算法说明
随机 随机选择一个服务实例,使用相对较少
轮询 依次分配请求,负载均衡默认实现方式
加权轮询 根据服务器性能与负载分配不同权重,性能越好权重越高
地址哈希 对客户端地址进行哈希计算并取模,映射到固定服务器
最小连接数 将请求分配到当前连接数最少的服务器,实现压力均衡

四、Ribbon 原理(旧版)

虽然新版本 Spring Cloud 已不再默认集成 Ribbon,但由于很多企业仍在使用旧版本,了解其原理仍有必要。
Ribbon 是 Netflix 开源的客户端负载均衡工具,常与 RestTemplate 或 Feign 配合使用。

在这里插入图片描述


五、Spring Cloud LoadBalancer(新版替代方案)

从 Spring Cloud 2020.0 版本起,原有的 Netflix 组件(除 Eureka 外)已逐步被替代。Spring Cloud LoadBalancer 是官方推荐的 Ribbon 替代品。

Netflix 组件推荐替代方案
Hystrix Sentinel、Resilience4j
Ribbon Spring Cloud LoadBalancer
Zuul 1 Spring Cloud Gateway
Archaius 1 Spring Boot 外部化配置 + Spring Cloud Config

Spring Cloud LoadBalancer 目前支持轮询与随机两种负载均衡策略,默认为轮询。

1. 配置随机负载均衡

(1)配置类

@Configuration
public class LoadBalancerConfig {
@Bean
ReactorLoadBalancer<ServiceInstance> reactorLoadBalancer(Environment environment,
LoadBalancerClientFactory loadBalancerClientFactory) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new RandomLoadBalancer(
loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class),
name
);
}
}

(2)在启动类中指定负载均衡策略

// 为指定服务配置负载均衡策略
@LoadBalancerClient(value = "mall-order", configuration = LoadBalancerConfig.class)

// 或全局默认配置
@LoadBalancerClients(defaultConfiguration = LoadBalancerConfig.class)

在这里插入图片描述

2. LoadBalancer 工作原理(RestTemplate + LoadBalancer)

当我们通过服务名发起请求时,LoadBalancer 会将其转换为 ip:port 形式。核心流程如下:

核心类:LoadBalancerAutoConfiguration

  • SmartInitializingSingleton
    Spring 容器在所有单例 Bean 初始化完成后,会回调其 afterSingletonsInstantiated() 方法。

  • 定制 RestTemplate
    在回调方法中,为所有带有 @LoadBalanced 注解的 RestTemplate 添加定制器 RestTemplateCustomizer。

  • 添加拦截器
    该定制器向 RestTemplate 加入拦截器 LoadBalancerInterceptor。

  • 拦截请求
    当使用 RestTemplate 发送请求时,拦截器生效,执行 intercept() 方法。

  • 负载均衡选择实例
    调用 loadBalancer.execute(),实际由 BlockingLoadBalancerClient 实现。
    进一步调用 choose() 方法,通过 LoadBalancerClientFactory 获取负载均衡器,并选取一个 ServiceInstance 完成调用。

  • 在这里插入图片描述

    流程总结:

  • LoadBalancerAutoConfiguration 收集所有带有 @LoadBalanced 注解的 RestTemplate。
  • 通过 RestTemplateCustomizer 为每个 RestTemplate 添加拦截器 LoadBalancerInterceptor。
  • 拦截器依赖 LoadBalancerClient 和 LoadBalancerRequestFactory 执行负载均衡逻辑。
  • 最终由具体的负载均衡器(如 RoundRobinLoadBalancer 或 RandomLoadBalancer)选择一个实例发起请求。
  • 轮询算法( RoundRobinLoadBalancer):

    在这里插入图片描述

    随机算法(RandomLoadBalancer):

    在这里插入图片描述


    六、总结

  • 初始化阶段
    Spring 容器中的 LoadBalancerAutoConfiguration 会注册一个 SmartInitializingSingleton 组件,该组件在所有单例 Bean 初始化完成后自动执行 afterSingletonsInstantiated() 方法,为 RestTemplate 添加定制器。

  • 定制 RestTemplate
    定制器 RestTemplateCustomizer 为 RestTemplate 添加拦截器 LoadBalancerInterceptor。

  • 请求拦截与负载均衡
    当通过 RestTemplate 发送请求时,拦截器生效,调用负载均衡器(如 RoundRobinLoadBalancer 或 RandomLoadBalancer)选择一台实例完成调用。

  • 策略支持
    Spring Cloud LoadBalancer 默认支持轮询与随机两种策略,可通过配置类灵活切换。

  • 赞(0)
    未经允许不得转载:171主机测评 » Ribbon&LoadBalancer负载均衡原理
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址