Ribbon负载均衡

简介: 本节深入解析Ribbon实现客户端负载均衡的原理,详解@LoadBalanced注解作用,剖析负载均衡策略、自定义配置及饥饿加载优化,帮助读者全面掌握Ribbon在Spring Cloud中的应用与底层机制。

在上一节我们引入Eureka的同时,不知读者朋友们是否还有印象:我们在启动类getRestTemplate方法上追加了注解 @LoadBalanced,为什么加这个注解?这个注解解决了什么问题?本节笔者将给读者们做详尽的讲解。
1.负载均衡
1.1 什么是负载均衡
传统架构下的网站,随着流量的增加,高并发、海量数据的挑战逐步而来。为了提升系统的性能,架构师们往往开始从垂直扩展、水平扩展两个角度来解决问题:
垂直扩展
网站发展的早期可以通过增加服务器的硬件处理能力:CPU、内存、磁盘等方面提升服务器处理的能力,然而单机的瓶颈总是存在的,一旦触及瓶颈想再提升,付出的成本会极高,显然这不符合分布式系统的设计理念。
水平扩展
通过集群部署的方式,将一台服务器的请求压力,分摊到多台机器上,集群中的应用服务器通常被设计成无状态。但是如何将流量均匀分摊到各机器上,或优先分配到高性能机器上又成了一个问题,由此引申出“负载均衡”的概念。
负载均衡(Load Balance)是如今高并发、高可用系统中不可或缺的关键组件,目标是:尽力将用户流量按照架构设计分发(并非一定均匀)到集群中多台服务器上,从而提高系统整体的响应速度和可用性。
1.2 负载均衡分类
硬件负载均衡(包括但不限于)
● F5
● A10
软件负载均衡(包括但不限于)
● Nginx
● HAProxy
● LVS
1.3 负载均衡算法
为不影响章节重点,需做进一步了解的可移步:负载均衡算法
2.Ribbon如何实现负载均衡
Ribbon与大多数负载均衡实现机制一样在客户端实现(不同于后续我们讲解的Nacos,Nacos在服务端实现),其主要流程为:
● 在RestTemplate标注@LoadBalanced注解,此时通过RestTemplate发起的RESTful请求都会被负载均衡
● 当请求发起时,会被LoadBalancedInterceptor拦截,其主要实现两个功能:
○ 从多个可用Server中选择一个Server,选择算法即上述1.3中之一
○ 重构请求URI:服务名-->具体ip、端口
● LoadBalancerClient内部持有LoadBalancer并调用getServer方法得到一个Server,而这个Server是通过Eureka服务注册,ILoadBalancer持有的upServerList、allServerList中获取(底层依赖ServerListUpdater动态更新所有serverList)
完整源码交互流程总结如下,感兴趣的可做进一步研究:

3.Ribbon自定义负载均衡策略
1.代码声明式注册
在启动类追加以下代码即可,此优先级更高,但修改必须重启应用,且全局生效
@Bean
public IRule getRandomRule() {
return new RandomRule();
}
通过查看IRule实现类,可以做其余负载均衡实现方案的更多测试

2.配置文件声明式配置
此配置优点在于不用重启应用,打包发布,但缺点是无法做到全局配置,必须声明规则对应的服务
userservice: # 给某个微服务配置负载均衡规则,这里是userservice服务
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则
4.Ribbon饥饿加载
在上述的测试中不知是否有读者发现:当请求第一次到某个实例时,其响应速度明细要慢一点,这里就是因为Ribbon默认采用饥饿加载,只有访问时才会创建LoadBalanceClient,从而导致第一次时间要长点,日志如下:
● 修改饥饿加载前启动日志

● 修改饥饿加载前访问日志

修改饥饿加载机制,通过在配置文件中追加以下配置即可
ribbon:
eager-load:
enabled: true # 开启饥饿加载
clients: userservice # 指定饥饿加载服务
● 修改饥饿加载后启动日志

● 修改饥饿加载后访问日志

至此我们的工程如下,有需自行下载导入:
5.总结
上一节就已经实现的负载均衡笔者并未深入探讨,本节通过分析负载均衡算法、Ribbon实现负载均衡的底层原理和实现过程,让大家对负载均衡有了一个大体认识,同时针对Ribbon自定义负载均衡策略,饥饿加载让大家对于Ribbon的了解又多一些。Ribbon实现的负载均衡只是方案之一,我们可以尽量多了解但不要局限于此。
负载均衡作为现如今架构必须考量的一个点,要了解和深入学习的地方还很多,如下一节我们要学习的Nacos是怎么实现的?它为什么反其道而行要在服务端实现?ZK也可作为注册中心它是怎么实现的?网关GateWay也可做负载均衡它又是怎么实现的呢?篇幅问题,更多的答案留给读者朋友们在未来的工作生涯中慢慢思考。

思考问题
● Ribbon是什么?解决了什么问题?
● Ribbon实现的是客户端,还是服务端负载均衡?
● Ribbon如何实现负载均衡?
● 还有哪些技术点可以实现负载均衡?
● 负载均衡算法?如何实现?还有哪些技术有体现?

6.推荐阅读资料
● 了解负载均衡算法:阿里云实操课程链接
● 掌握Ribbon实现负载均衡原理:本文链接

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
相关文章
|
5月前
|
存储 监控 Java
整合切面,参数拦截+过滤
该类基于Spring AOP实现请求参数日志拦截,自动记录请求来源、URL、方式、方法及入参,并统计接口耗时。通过@Pointcut拦截controller层请求,结合@Before、@After与@Around实现前后置通知,便于调试与监控,日志输出至指定文件,支持后续扩展存储或分析。
|
5月前
|
Apache
Excel工具-HUTOOL-读取Excel
基于Hutool和Apache POI,封装Excel读取工具,支持xls/xlsx格式。可读取为List、Map或Bean,提供Sax模式(Excel03SaxReader/Excel07SaxReader)高效处理大文件,避免内存溢出,适用于海量数据流式读取。
|
5月前
|
Java 大数据 Apache
Excel工具-HUTOOL-输出Excel
Hutool基于Apache POI封装了Excel读写功能,提供ExcelWriter和BigExcelWriter类,支持写出List、Map、Bean等数据类型到Excel,可自定义样式、多sheet操作,并解决大数据量导出时的内存溢出问题,适用于文件导出、客户端下载等场景。
|
5月前
|
SQL Dubbo Java
线程池:故障梳理总结
本文从故障与技术双重视角,总结线程池类问题的常见成因与防范策略。通过真实案例剖析数据库慢查询、连接池配置不当、超时设置缺失等引发的线程池满故障,提出fast-fail、合理超时、流控背压等最佳实践,助力开发者提升系统稳定性。
|
5月前
|
存储 安全 Java
Java泛型类型擦除以及类型擦除带来的问题
Java泛型在编译时会进行类型擦除,仅保留原始类型(如Object或限定类型)。例如,List<String>和List<Integer>在运行时均为List,导致无法通过instanceof判断泛型类型。类型检查在编译期完成,基于引用而非对象本身。擦除后,编译器自动插入强制类型转换以保证类型安全。但这也引发与多态冲突、静态成员不能使用类泛型等问题。反射可绕过泛型限制,证明类型信息已丢失。基本类型不可作为泛型参数,需使用包装类。
|
5月前
|
安全 Java 开发工具
工程搭建与验证
本文介绍如何基于阿里云脚手架快速搭建SpringBoot工程(选用2.7.6版本),并整合Spring Security。内容涵盖项目创建、代码导入、Web依赖引入、接口编写与验证,以及Spring Security的集成与默认登录验证。通过简单步骤实现安全控制,源码可从指定GitHub仓库获取。
|
5月前
|
存储 安全 小程序
认识OAuth2.0
OAuth2.0是一种开放授权标准,允许第三方应用在用户授权下安全访问资源,无需获取用户账号密码。它通过令牌机制实现权限控制,广泛用于API访问、第三方登录等场景,支持授权码、简化、密码和客户端四种模式,保障系统间资源共享的安全性与灵活性。
|
5月前
|
前端开发 程序员 开发者
常见注解及使用说明
本文介绍了SpringMVC中@RequestMapping注解的作用,通过注解将HTTP请求映射到控制器方法,实现前后端接口路径对应。并讲解了@GetMapping等派生注解的使用,帮助开发者快速掌握接口定义原理与实践。
|
5月前
|
SQL NoSQL 前端开发
大厂如何解决订单幂等问题
为保障分布式系统数据一致性,需实现接口幂等性。创建订单时,通过预生成全局唯一订单号,利用数据库主键唯一约束,防止重复插入;支付等操作借助Redis或状态表记录处理标识,避免重复执行。针对ABA问题,引入版本号机制,更新时校验并自增版本号,确保数据更新的正确性与一致性。该方案可通用化复用。
|
5月前
|
SQL 安全 网络协议
常见的网络攻击
恶意软件、网络钓鱼、中间人攻击、DDoS攻击、SQL注入、零日漏洞及DNS隧道是常见网络安全威胁。恶意软件窃取数据或破坏系统;网络钓鱼伪装可信来源骗取信息;中间人攻击窃听通信;DDoS以海量流量瘫痪服务;SQL注入操控数据库;零日攻击利用未修复漏洞;DNS隧道则隐蔽传输恶意数据,均需严密防范。