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 默认支持轮询与随机两种策略,可通过配置类灵活切换。

相关推荐
昊叔Crescdim2 小时前
Sonic数字人支持负载均衡部署,应对高并发请求
负载均衡·数字人·sonic
srhtrnbdfg2 小时前
Discuz!NT负载均衡方案
运维·负载均衡
sysinside2 小时前
VMware Avi Load Balancer 30.2.5 - 多云负载均衡平台
负载均衡·avi
问道飞鱼2 小时前
【服务器知识】nginx配置负载均衡完全解读
服务器·nginx·负载均衡
前路不黑暗@3 小时前
Java项目:Java脚手架项目的地图服务(十)
java·数据库·spring boot·笔记·学习·spring cloud·maven
前路不黑暗@6 小时前
Java项目:Java脚手架项目通用基类和常量类的封装(九)
java·spring boot·笔记·学习·spring cloud·maven·intellij-idea
之歆6 小时前
LVS 负载均衡完全指南
运维·负载均衡·lvs
前路不黑暗@9 小时前
Java项目:Java脚手架项目的地图的POJO
android·java·开发语言·spring boot·学习·spring cloud·maven
利刃大大10 小时前
【SpringCloud】远程调用OpenFeign && 快速入手 && 参数传递 && 继承方式 && 抽取方式 && 远程部署
后端·spring·spring cloud·openfeign·远程调用