Spring Cloud之Ribbon负载均衡及其应用
nginx - 随笔分类 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中涉及到负载均衡,为何此处由涉及Ribbon负载均衡呢?那是因为ngnix是服务端的负责均衡,而Ribbon是客户端的负载均衡。
对于负载均衡理论相关的内容nginx - 随笔分类 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中没有太多的涉及。此处补充如下:
负载均衡⼀般分为服务器端负载均衡和客户端负载均衡。
所谓服务器端负载均衡,⽐如Nginx、 F5这些,请求到达服务器之后由这些负载均衡器根据一定的算法将请求路由到模板服务器处理。
所谓客户端负载均衡,⽐如我们要说的Ribbon,服务消费者客户端会有⼀个服务器地址列表,调用方在请求前通过一定的负责均衡算法选择一个服务器进行访问,负载均衡算法选择一个服务器进行访问,负载均衡算法的执⾏是在请求客户端进⾏。
其在Cloud体系架构中为如下图中红框部分:
Ribbon的使用相对比较简单,其一般与Eureka配合使用:Ribbon利用从Eureka中读取到的服务信息,在调用服务提供者提供的服务时根据相应算法进行负载均衡。具体应用如下:
1、无需另外导入jar,因为Eureka相关包中已经包含:
2、修改嵌套调用服务添加@LoadBalanced:
3、修改Resume测试案例:
4、测试结果:
测试过程中遇到几个小问题:
1)无法找到服务,原因是使用了ribbon负载均衡后不可直接使用ip:port地址进行路由了,而是必需使用spring.application.name里配置的名称。为什么呢?可以看下使用ribbon进行客户端负载均衡后,eureka的内容:
本机的ip是:
但是注册到eureka之后是两个地址,所以不使用硬编码的方式进行访问
2)使用spring.application.name里配置的名称后,提示Request URI does not contain a valid hostname: http://XXX/XX/openstate/XX。这是因为ribbon不支持应用名中间包含下划线“_”,支持应用名中间包含连接线“-”。
所以除了以上修改外还需修改被嵌套调用的路由:
配置文件中关于spring.application.name部分内容同步修改。
注意:通过restTemplate进行访问时并没有使用具体的用户微服务地址,取而代之的事用户微服务的服务名称;当镜像访问时,服务治理客户端会根据该名称查询相应的服务实例有哪些,并从这些服务实例中选择一个进行访问。这个与之前没有使用@LoadBalanced一个大的不同,如果不使用该注解可以发现该用法不好使,这是因为仅使用Eureka开启相关服务不支持服务名映射到相应地址进行访问。
以上案例通过给所使用的RestTemplate添加@LoadBalanced注解开启负责均衡功能。通过该注解,Ribbon为Rest客户端(RestTemplate)的实现增加了客户端负载均衡功能,其实现原理可以概括如下:
1)Ribbon首先根据其所在Zone优先选择一个负载较少的Eureka服务器;
2)定期从Eureka服务器更新,并过滤服务实例列表;
3)根据指定的负责均衡策略从可用的服务实例列表中选择一个;
4)然后使用该地址通过Rest客户端进行服务调用。
具体实现通过跟踪源码进行后续分析。
本篇及前几篇文章通过使用Java及Spring Boot架构实现了服务治理,可以回顾下服务治理的具体关注:
那么如果不采用上述架构可以依然使用Eureka+Ribbon达到服务治理的目的么?当然可以。微服务架构是不强求使用同一种技术栈的,提供了一个方案就是Sidecar——具体可参考Spring Cloud Netflix。通过Sidecar可以将异构的服务加入到Spring Cloud所构建的服务架构体系中。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?