LoadBalancer 和 Ribbon 的区别是什么?为什么用它替代 Ribbon?
一则或许对你有用的小广告
欢迎 加入小哈的星球 ,你将获得: 专属的项目实战(已更新的所有项目都能学习) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新开坑项目: 《Spring AI 项目实战(问答机器人、RAG 增强检索、联网搜索)》 正在持续爆肝中,基于
Spring AI + Spring Boot3.x + JDK 21..., 点击查看; - 《从零手撸:仿小红书(微服务架构)》 已完结,基于
Spring Cloud Alibaba + Spring Boot3.x + JDK 17..., 点击查看项目介绍; 演示链接: http://116.62.199.48:7070/; - 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/
面试考察点
-
框架演进认知:面试官不仅仅是想知道 LoadBalancer 和 Ribbon 的功能差异,更是想考察你是否关注 Spring Cloud 生态的版本演进,是否了解从 Netflix OSS 到 Spring Cloud 自研组件的迁移脉络。
-
负载均衡原理:考察你对客户端负载均衡的理解深度——是否清楚服务发现、服务选择、健康检查这些核心机制。
-
技术选型意识:能否说清楚为什么官方要 "弃 Ribbon 转 LoadBalancer",这背后反映的是你对技术生命周期和维护策略的判断力。
核心答案
Ribbon 是 Netflix 开源的客户端负载均衡组件,Spring Cloud LoadBalancer 是 Spring 官方推出的替代方案。 替换的根本原因是 Ribbon 已进入维护模式(Maintenance Mode),不再积极更新。
核心区别一览:
| 对比维度 | 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。
深度解析
一、为什么 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 官方不可能让自己的生态依赖一个不再更新的第三方库,所以必须寻找或自研替代方案。
二、两者架构对比
从架构图可以看出两者的设计思路差异:
- Ribbon:采用自己的接口体系(
ServerList、IRule、IPing),与 Netflix 生态深度绑定。 - LoadBalancer:采用 Spring 风格的接口设计(
ServiceInstanceListSupplier、ReactiveLoadBalancer),与 Spring 生态无缝融合,并且天然支持响应式编程。
三、负载均衡策略对比
两者都支持常见的负载均衡策略,但实现方式不同:
| 策略 | Ribbon 实现 | LoadBalancer 实现 |
|---|---|---|
| 轮询 | RoundRobinRule | RoundRobinLoadBalancer(默认) |
| 随机 | RandomRule | RandomLoadBalancer |
| 加权 | WeightedResponseTimeRule | 需自定义或配合 Nacos 权重 |
| 最佳可用 | BestAvailableRule | 需自定义 |
| 哈希 | 无内置 | 无内置 |
LoadBalancer 默认使用轮询策略,如果需要切换策略,可以通过自定义 LoadBalancerClient 配置来实现。
四、代码实战对比
Ribbon 方式(旧):
// application.yml 配置
// user-service:
// ribbon:
// NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
// 直接使用 @LoadBalanced RestTemplate
@Configuration
public class RibbonConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new 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
);
}
}
LoadBalancer 方式(新):
// 1. 添加依赖(Spring Cloud 2020.x+ 自动包含)
// spring-cloud-starter-loadbalancer
// 2. 使用方式几乎一致
@Configuration
public class LoadBalancerConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new 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 的响应式调用。
五、迁移注意事项
如果你从 Ribbon 迁移到 LoadBalancer,需要注意以下几点:
-
排除 Ribbon 依赖:确保
pom.xml中不再引入spring-cloud-starter-netflix-ribbon,否则可能与 LoadBalancer 产生冲突。 -
缓存配置:Ribbon 自带缓存,而 LoadBalancer 需要显式引入 Spring Cache 实现(如 Caffeine):
<dependency> <groupId>com.github.ben-manes.caffeine</groupId> <artifactId>caffeine</artifactId> </dependency> -
自定义策略:Ribbon 通过配置文件切换策略(
NFLoadBalancerRuleClassName),LoadBalancer 需要通过 Java 配置类自定义ReactiveLoadBalancer实现。 -
健康检查:Ribbon 通过
IPing内置实现,LoadBalancer 需要配合服务注册中心(如 Nacos)的健康检查机制。
面试高频追问
-
追问一:LoadBalancer 支持哪些负载均衡策略?如何自定义?
- 内置轮询(默认)和随机两种。自定义策略需要实现
ReactorServiceInstanceLoadBalancer接口,注册为@Bean即可。
- 内置轮询(默认)和随机两种。自定义策略需要实现
-
追问二:客户端负载均衡和服务端负载均衡有什么区别?
- 客户端负载均衡(Ribbon / LoadBalancer):由调用方自己选择服务实例,不需要中间代理。服务端负载均衡(Nginx / F5):由代理服务器选择后端实例。前者性能更好(少一跳),后者与语言无关。
-
追问三:Spring Cloud 2020.x 之后还有哪些 Netflix 组件被替换了?
- Ribbon → LoadBalancer,Hystrix → Sentinel / Resilience4J,Zuul → Spring Cloud Gateway。Eureka 暂时保留但仍可用,推荐迁移到 Nacos。
常见面试变体
- 变体一:"Spring Cloud 为什么要替换掉 Ribbon?"
- 变体二:"说说 Spring Cloud 版本演进中组件的变化。"
- 变体三:"客户端负载均衡的原理是什么?"
- 变体四:"如何在 Spring Cloud 中自定义负载均衡策略?"
记忆口诀
Ribbon 已退休,LoadBalancer 接班:Ribbon 停更是因为 Netflix OSS 全线停更,不是 Ribbon 自身的问题。新项目直接用 LoadBalancer,老项目迁移只需换依赖、加缓存、调策略,三步搞定。记住迁移三件事:排依赖、加缓存、改策略。
总结
Ribbon 被 LoadBalancer 替代的根本原因是 Netflix OSS 生态全线停更,Spring 官方必须掌握核心组件的主动权。LoadBalancer 更轻量、拥抱 Reactive、与 Spring 生态无缝集成,是 Spring Cloud 2020.x 及之后版本的默认负载均衡方案。迁移成本低,新项目直接用 LoadBalancer 即可。