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 简介

Ribbon 是 Netflix 开源的客户端负载均衡组件,Spring Cloud LoadBalancer 是 Spring 官方推出的替代方案。 替换的根本原因是 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 已停更 "退休",LoadBalancer 是 Spring 官方推出的 "继任者",功能更轻量、拥抱 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)的健康检查机制。

相关推荐
EAIReport7 小时前
SpringBoot 与 SpringCloud 深度解析:核心特点、差异与协同关系
spring boot·后端·spring cloud
Wang's Blog8 小时前
Java 项目实战: 交友项目 - SpringCloud 整合 Dubbo 的方案概述
java·spring cloud·交友
Thomas.Sir1 天前
第23课:Sentinel熔断降级、系统自适应保护、集群限流
spring cloud·sentinel
2501_933923252 天前
SpringCloud组件:Eureka服务注册与发现
java·开发语言·后端·spring cloud·eureka
叶总没有会2 天前
Gateway--网关
spring cloud·微服务·gateway
海马3 天前
Spring Cloud 开发知识整理
spring·spring cloud·wpf
骑着蜗牛撵大象3273 天前
服务下线不再炸:分层关闭、TCP 存活探测与负载均衡排水的落地套路
android·tcp/ip·负载均衡·tcp·高可用·健康检查·优雅关闭
栗子~~3 天前
SpringCloud Gateway 基于 Nacos 实现动态路由
java·spring cloud·gateway
code_slave(码畜)3 天前
微服务架构落地:消息队列架构设计(上篇)——异步解耦、削峰填谷,看懂业务事件流转本质
spring boot·spring cloud·微服务·云原生·架构
code_slave(码畜)3 天前
微服务架构落地:消息队列架构设计(下篇)——消息堆积、死信治理与集群监控告警实战
spring boot·spring cloud·微服务·云原生·中间件·架构