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)的健康检查机制。

相关推荐
Linux-lucky8 小时前
46-Linux学习之旅之LVS负载均衡与keepalived高可用
linux·运维·学习·ubuntu·负载均衡·lvs
code_slave(码畜)15 小时前
微服务架构落地:慢 SQL 治理与连接池调优 —— 守住数据库的最后一道防线
数据库·spring boot·sql·spring cloud·微服务·架构
2501_933923252 天前
SpringCloud:OpenFeign快速实现
java·后端·spring cloud·openfeign
逃逸线LOF2 天前
为什么需要Actuator进行静态检查
spring cloud·eureka
水无痕simon3 天前
3、工程重构
java·spring cloud·重构
shuair3 天前
Spring Cloud 微服务脚手架:Simple Cloud 系统架构设计
spring cloud·微服务·系统架构
小羊没烦恼!3 天前
关于分布式锁原理的一些学习与思考-redis分布式锁,zookeeper分布式锁
java·服务器·网络·学习·负载均衡
知已难寻6 天前
00 · OpenStack 总纲——从云计算到 OpenStack 全景
运维·服务器·云原生·云计算·负载均衡·openstack·perl
七夜zippoe6 天前
Agent 网关设计:统一入口、智能路由与负载均衡
运维·ai·log4j·负载均衡·agent·网关设计
Vitaliy Kostrov(柯维远)7 天前
Multi-CDN 决策闭环:QoE、成本、安全与内容正确性如何进入同一个策略引擎?
安全·网络安全·云计算·音视频·负载均衡·cdn