SpringCloud之负载均衡 Ribbon和LoadBalancer讲解

文章目录

  • [1 负载均衡](#1 负载均衡)
    • [1.1 简介](#1.1 简介)
      • [1.1.1 二者区别](#1.1.1 二者区别)
      • [1.1.2 为什么 Ribbon 被淘汰](#1.1.2 为什么 Ribbon 被淘汰)
    • [1.2 原理讲解](#1.2 原理讲解)
      • [1.2.1 架构对比](#1.2.1 架构对比)
      • [1.2.2 负载均衡策略对比](#1.2.2 负载均衡策略对比)
    • [1.3 代码对比](#1.3 代码对比)
      • [1.3.1 Ribbon 方式(旧)](#1.3.1 Ribbon 方式(旧))
      • [1.3.2 LoadBalancer 方式(新)](#1.3.2 LoadBalancer 方式(新))
    • [1.4 迁移注意](#1.4 迁移注意)

1 负载均衡

1.1 简介

RibbonNetflix 开源的客户端负载均衡组件,Spring Cloud LoadBalancerSpring 官方推出的替代方案。 替换的根本原因是 Ribbon 已进入维护模式(Maintenance Mode),不再积极更新。

客户端负载均衡和服务端负载均衡有什么区别?

客户端负载均衡(Ribbon / LoadBalancer):由调用方自己选择服务实例,不需要中间代理。服务端负载均衡(Nginx / F5):由代理服务器选择后端实例,前者性能更好(少一跳),后者与语言无关

1.1.1 二者区别

核心区别一览:

对比维度 Ribbon Spring Cloud LoadBalancer
维护方 Netflix(已停更) Spring 官方(持续迭代)
状态 维护模式,不再新增功能 活跃开发中
所属生态 Netflix OSS Spring Cloud 自研
缓存机制 自带 Spring 缓存(SpringClientFactory) 依赖 Spring Cache(如 Caffeine)
配置方式 基于 .properties / .yml 细粒度配置 基于 LoadBalancerClient 配置
依赖体积 较重,依赖较多 轻量,核心包很小
Reactive 支持 不支持 天然支持 Reactive(WebClient)
默认集成 Spring Cloud 2020.x 之前 Spring Cloud 2020.x 及之后

一句话总结:Ribbon 已停更 "退休",LoadBalancerSpring 官方推出的 "继任者",功能更轻量、拥抱 Reactive,新项目必须用 LoadBalancer

1.1.2 为什么 Ribbon 被淘汰

Ribbon 被替换不是因为它不好用,而是 Netflix OSS 全线停更带来的连锁反应。

上图展示了 Spring Cloud Netflix 组件的 "退役" 时间线。

关键要点:

  • 2015 年前后,Spring Cloud Netflix 是微服务领域的事实标准,Eureka + Ribbon + Hystrix + Zuul 组合几乎成了 "标配"。
  • 2018 ~ 2019 年,Netflix 陆续宣布核心组件进入维护模式,不再积极开发新功能。
  • 2020 年,Spring 官方在 Spring Cloud 2020.x(代号 Ilford)中正式移除了 Netflix 依赖,推出了自研替代方案。
    核心逻辑:Spring 官方不可能让自己的生态依赖一个不再更新的第三方库,所以必须寻找或自研替代方案。

1.2 原理讲解

1.2.1 架构对比

从架构图可以看出两者的设计思路差异:

  • Ribbon:采用自己的接口体系(ServerList、IRule、IPing),与 Netflix 生态深度绑定。
  • LoadBalancer:采用 Spring 风格的接口设计(ServiceInstanceListSupplier、ReactiveLoadBalancer),与 Spring 生态无缝融合,并且天然支持响应式编程

1.2.2 负载均衡策略对比

两者都支持常见的负载均衡策略,但实现方式不同:

策略 Ribbon 实现 LoadBalancer 实现
轮询 RoundRobinRule RoundRobinLoadBalancer(默认)
随机 RandomRule RandomLoadBalancer
加权 WeightedResponseTimeRule 需自定义或配合 Nacos 权重
最佳可用 BestAvailableRule 需自定义
哈希 无内置 无内置

LoadBalancer 默认使用轮询策略,如果需要切换策略,可以通过自定义 LoadBalancerClient 配置来实现。

1.3 代码对比

1.3.1 Ribbon 方式(旧)

java 复制代码
// application.yml 配置
// user-service:
//   ribbon:
//     NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

// 直接使用 @LoadBalanced RestTemplate
@Configuration
public class RibbonConfig {
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        returnnew RestTemplate();
    }
}

// 调用
@RestController
public class OrderController {
    @Autowired
    private RestTemplate restTemplate;
    public User getUser(Long userId) {
        // Ribbon 拦截请求,根据服务名选择实例
        return restTemplate.getForObject(
            "http://user-service/api/users/" + userId,
            User.class
        );
    }
}

1.3.2 LoadBalancer 方式(新)

java 复制代码
// 1. 添加依赖(Spring Cloud 2020.x+ 自动包含)
// spring-cloud-starter-loadbalancer

// 2. 使用方式几乎一致
@Configuration
public class LoadBalancerConfig {
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        returnnew RestTemplate();
    }
    // 3. 也可以搭配 WebClient(Reactive 方式)
    @Bean
    @LoadBalanced
    public WebClient.Builder webClientBuilder() {
        return WebClient.builder();
    }
}

// 调用方式不变
@RestController
public class OrderController {

    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private WebClient.Builder webClientBuilder;
    // 同步调用
    public User getUser(Long userId) {
        return restTemplate.getForObject(
            "http://user-service/api/users/" + userId,
            User.class
        );
    }
    // Reactive 调用(Ribbon 做不到)
    public Mono<User> getUserReactive(Long userId) {
        return webClientBuilder.build()
            .get()
            .uri("http://user-service/api/users/" + userId)
            .retrieve()
            .bodyToMono(User.class);
    }
}

可以看到,迁移成本其实很低------@LoadBalanced 注解照用,调用方式不变。LoadBalancer 还额外支持 WebClient 的响应式调用。

1.4 迁移注意

如果从 Ribbon 迁移到 LoadBalancer,需要注意以下几点:排除 Ribbon 依赖:确保 pom.xml 中不再引入 spring-cloud-starter-netflix-ribbon,否则可能与 LoadBalancer 产生冲突。

缓存配置:Ribbon 自带缓存,而 LoadBalancer 需要显式引入 Spring Cache 实现(如 Caffeine):

xml 复制代码
<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
</dependency>

自定义策略:Ribbon 通过配置文件切换策略(NFLoadBalancerRuleClassName),LoadBalancer 需要通过 Java 配置类自定义 ReactiveLoadBalancer 实现。

健康检查:Ribbon 通过 IPing 内置实现,LoadBalancer 需要配合服务注册中心(如 Nacos)的健康检查机制。

相关推荐
Java识堂10 小时前
多级负载均衡架构
运维·架构·负载均衡
小黑蛋学java14 小时前
Nginx 接口耗时 Prometheus + Grafana 监控实施方案
运维·nginx·负载均衡·grafana·prometheus
运维瓦工18 小时前
DevOps 生态介绍(十):Docker Compose 核心 YAML 配置详解与常用命令大全
spring cloud·docker·容器
worilb20 小时前
Spring Cloud 学习与实践(8):Spring Cloud Gateway 统一入口、路由转发与双重跨域故障演练
学习·spring·spring cloud
Devin~Y1 天前
大厂 Java 面试实战:从 Spring Boot 微服务到 AI RAG 音视频平台全链路解析
java·spring boot·redis·spring cloud·微服务·rag·spring ai
我登哥MVP1 天前
SpringCloud 核心组件解析:服务注册与发现
java·spring boot·后端·spring·spring cloud·java-ee·maven
難釋懷1 天前
Nginx使用sticky模块完成对Nginx的负载均衡
运维·nginx·负载均衡
盒子69101 天前
图生图大模型对于各种复杂的图片如何做负载均衡呢?
运维·负载均衡
2401_834636991 天前
Linux 负载均衡全实战:Nginx+HAProxy+LVS 从原理到落地
linux·nginx·负载均衡