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)配置类

java 复制代码
@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)在启动类中指定负载均衡策略

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

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

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

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

核心类:LoadBalancerAutoConfiguration

  1. SmartInitializingSingleton

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

  2. 定制 RestTemplate

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

  3. 添加拦截器

    该定制器向 RestTemplate 加入拦截器 LoadBalancerInterceptor

  4. 拦截请求

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

  5. 负载均衡选择实例

    调用 loadBalancer.execute(),实际由 BlockingLoadBalancerClient 实现。

    进一步调用 choose() 方法,通过 LoadBalancerClientFactory 获取负载均衡器,并选取一个 ServiceInstance 完成调用。

流程总结:

  1. LoadBalancerAutoConfiguration 收集所有带有 @LoadBalanced 注解的 RestTemplate。
  2. 通过 RestTemplateCustomizer 为每个 RestTemplate 添加拦截器 LoadBalancerInterceptor
  3. 拦截器依赖 LoadBalancerClientLoadBalancerRequestFactory 执行负载均衡逻辑。
  4. 最终由具体的负载均衡器(如 RoundRobinLoadBalancerRandomLoadBalancer)选择一个实例发起请求。

轮询算法( RoundRobinLoadBalancer

随机算法(RandomLoadBalancer


六、总结

  1. 初始化阶段

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

  2. 定制 RestTemplate

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

  3. 请求拦截与负载均衡

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

  4. 策略支持

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

相关推荐
tongluowan00719 小时前
负载均衡之硬件与软件层面的异同
运维·nginx·负载均衡·f5
椰椰椰耶21 小时前
[SpringCloud][12]Nacos配置中心详解,快速上手,Nacos和Eureka的区别
spring·spring cloud·eureka
半旧夜夏1 天前
【保姆级】微服务组件环境搭建(Docker Compose版)
java·linux·spring cloud·微服务·云原生·容器
阿狸猿2 天前
论系统负载均衡设计方法
运维·负载均衡
phltxy2 天前
RabbitMQ集群运维:仲裁队列与负载均衡
运维·rabbitmq·负载均衡
Devin~Y2 天前
从内容社区到AIGC客服:Spring Boot、Redis、Kafka、K8s、RAG的三轮大厂Java面试对话(附标准答案)
java·spring boot·redis·spring cloud·kafka·kubernetes·micrometer
西凉的悲伤2 天前
Spring Boot 、Spring Cloud 微服务架构认证授权方案
spring boot·spring cloud·微服务·架构·认证授权
phltxy3 天前
HAProxy安装与RabbitMQ负载均衡配置
分布式·rabbitmq·负载均衡
西凉的悲伤3 天前
Spring Cloud Gateway介绍
java·spring cloud·gateway