最新版Spring Cloud Alibaba微服务架构-Ribbon负载均衡篇
文章目录
- 前言
- 一、Ribbon核心概念
- 二、服务器端负载均衡和Riboon客户端负载均衡
- 1、服务器端负载均衡:
- 2、Riboon客户端负载均衡:
- 三、Ribbon策略
- 四、Ribbon配置使用
- 五、配置自定义的负载均衡算法
- 1、按照权重实现负载均衡
- 1.1 配置Ribbon
- 1.2 全局的负载均衡算法类
- 1.3 自定义权重实现负载均衡
- 1.4 设置Nacos服务实例权重比例
- 1.4 测试负载均衡
- 六、Ribbon常用配置
- 总结
前言
Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现。
一、Ribbon核心概念
Raibbon是基于Netflix Ribbon实现的一套客户端负载均衡工具。Raibbon客户端提供了一系列的配置,如超时、重试、负载均衡等,对Spring Cloud Ribbon的理解和使用,对于我们使用Spring Cloud来构建微服务非常重要,比如微服务之间的调用,API网关的转发请求等,实际上都是通过Ribbon来完成的。
通俗的来说:Ribbon = 负载均衡 + RestTemplate
这里提到了一个词,叫做客户端负载均衡,那么可能会想到我们的Nginx,那么Nginx是客户端负载均衡吗?不是,Nginx实际上是一种集中式负载均衡(服务器端负载均衡),并不属于客户端负载均衡范畴。那么这两者的区别是什么呢?
二、服务器端负载均衡和Riboon客户端负载均衡
1、服务器端负载均衡:
服务端负载均衡又分为两种,一种是硬件负载均衡,还有一种是软件负载均衡。
例如Nginx,是软件负载均衡,通过Nginx进行负载均衡,先发送请求,然后通过负载均衡算法,在多个服务器之间选择一个进行访问;即在服务器端再进行负载均衡算法分配,我们来看一张图,使用Nginx做的负载均衡策略。
2、Riboon客户端负载均衡:
例如spring cloud中的ribbon,客户端会有一个服务器地址列表,在发送请求前通过负载均衡算法选择一个服务器,然后进行访问,这是客户端负载均衡;即在客户端就进行负载均衡算法分配。来直接上图,下图所示是我们本篇文章要实现的Ribbon负载均衡策略。
三、Ribbon策略
当我们在 RestTemplate 上添加 @LoadBalanced 注解后,就可以用服务名称来调用接口了,当有多个服务的时候,还能做负载均衡。然而Ribbon客户端组件提供一系列完善的配置项,如连接超时,重试等,并且我们还能够使用Ribbon实现自定义的负载均衡策略。
负载均衡常用策略方式:
- 默认为轮训的策略方式
- 随机
- 重试(如果获取服务失败,在指定时间内进行重试,获取可用服务)
- 过滤掉出故障的服务,选择一个最小并发量的服务
如下图为负载均衡轮训算法的实现:
四、Ribbon配置使用
这里我们使用Nacos作为注册中心,模拟订单服务于库存服务之间的调用,使用Ribbon作为客户端的负载均衡实现,他的配置方式很简单,下面我们就搭建好以下三个服务,准备实操一波。
服务名称 | 端口号 |
---|---|
dt-stock-service | 8083 |
dt-stock-service | 8082 |
dt-order-service | 8081 |
这里我们的库存服务为两个,订单服务为一个,通过订单服务调用库存服务,实现Ribbon的负载均衡,首先是订单服务启动类,我们把RestTemplate 注册进来,这里我们使用RestTemplate 来实现服务之间的调用,RestTemplate 只需要加上 @LoadBalanced 注解后,就可以用服务名称来调用接口了,既能实现Ribbon的负载均衡策略。
@SpringBootApplication
@EnableDiscoveryClient
public class OrderApplication {public static void main(String[] args) {SpringApplication.run(OrderApplication.class, args);}@Bean@LoadBalancedpublic RestTemplate restTemplate(RestTemplateBuilder builder) {return builder.build();}
}
订单服务控制器调用接口如下:
@RestController
@RequestMapping(value = "order")
public class OrderController {@Autowiredprivate RestTemplate restTemplate;@GetMapping("test")public String getOrder() {String msg = restTemplate.getForObject("http://dt-stock-service/stock/test", String.class);return "调用订单服务->>>"+msg;}
}
我们通过服务名称的方式(dt-stock-service)来调用库存服务接口方法,然后我们再编写库存服务控制器接口方法:
@RestController
@RequestMapping(value = "/stock")
public class StockController {@Value("${server.port}")private String port;@GetMapping("/test")public String getStock() {return "调用库存服务:"+port;}
}
这里我们打印一下当前库存服务被调用的端口,以便观察Ribbon的负载均衡策略模式,服务架构如下。
我们启动8081订单服务,再依次启动8082、8083库存服务,服务启动之后,观察我们的注册中心服务实例变化,此时订单服务有一个实例,库存服务有两个实例,服务启动成功了,下面我们来发送接口测试:
发送请求:http://localhost:8081/order/test
第一次8083端口:
第二次8082端口:
一直发送接口请求测试,可以发现,都是8083和8082之间轮训切换调用,那就明白了,Ribbon默认的策略模式是轮询的方式,在文章开头我们说过Riboon的策略方式不止轮询,轮询只是它自身内部一种默认的实现方式,下面我们就来研究其他的几种常见的方式怎么玩?
五、配置自定义的负载均衡算法
1、按照权重实现负载均衡
Ribbon本身是没有权重的概念的, 那么如何才能实现代用权重的负载均衡呢? 我们在nacos中, 服务器的集群有一个权重的概念, 当给服务器设置了权重, 那么流量就可以根据权重比例分配到服务器上。
1.1 配置Ribbon
spring:application:name: dt-order-servicecloud:nacos:server-addr: 47.108.191.196:9091discovery:username: nacospassword: nacosnamespace: public
ribbon:NFLoadBalancerRuleClassName: com.dt.springcloud.ribbon.config.GlobalRibbonConfig #指定全局的负载均衡算法eager-load:enabled: true #开启饥饿模式clients: dt-stock-service #为哪些服务的名称开启饥饿加载,多个用逗号分隔
com.dt.springcloud.ribbon.config.GlobalRibbonConfig #指定全局的负载均衡算法类名
这里小编解释一下Ribbon为什么会有饥饿模式的配置:ribbon客户端不是在服务启动的时候加载的,所以可能第一次调用会很慢,甚至超时。
1.2 全局的负载均衡算法类
/*** 全局设置自定义的权重负载均衡策略* @author DT* @date 2021/8/7 20:39*/
@Configuration
public class GlobalRibbonConfig {@Beanpublic IRule getRule() {// 实现带有权重的负载均衡策略return new MyWeightRule();}}
1.3 自定义权重实现负载均衡
/*** 自定义一个权重负载均衡策略* @author DT* @date 2021/8/7 20:32*/
public class MyWeightRule extends AbstractLoadBalancerRule {@Autowiredprivate NacosDiscoveryProperties discoveryProperties;@Overridepublic void initWithNiwsConfig(IClientConfig iClientConfig) { }/*** 自定义实现负载均衡策略的方法*/@Overridepublic Server choose(Object key) {try {// 调用父类方法, 获取当前使用的负载均衡器BaseLoadBalancer baseLoadBalancer = (BaseLoadBalancer) this.getLoadBalancer();// 获取当前服务的名称String serviceName = baseLoadBalancer.getName();// 获取nacos的服务发现APINamingService namingService = discoveryProperties.namingServiceInstance();// nacos实现了权重的负载均衡算法Instance instance = namingService.selectOneHealthyInstance(serviceName);// 打印输出String threadName = Thread.currentThread().getName();System.out.println("线程->>>" + threadName + "->>>发送请求");System.out.println("IP端口->>>"+instance.getIp()+":"+instance.getPort());return new NacosServer(instance);} catch (NacosException e) {e.printStackTrace();}return null;}
}
1.4 设置Nacos服务实例权重比例
我们一个设置为0.3, 另一个设置成0.7, 也就是说如果有10次请求, 基本上都是会打到8082端口上的,因为8082的权重最高,打到它的接口数量应该是最多的。
1.4 测试负载均衡
http://localhost:8081/order/test
触发10次请求,基本7次左右都会打到8082服务上面。
六、Ribbon常用配置
ribbon:ConnectTimeout: 1000 #服务请求连接超时时间(毫秒)ReadTimeout: 3000 #服务请求处理超时时间(毫秒)OkToRetryOnAllOperations: true #对超时请求启用重试机制MaxAutoRetriesNextServer: 1 #切换重试实例的最大个数MaxAutoRetries: 1 #切换实例后重试最大次数NFLoadBalancerRuleClassName: com.dt.springcloud.ribbon.config.GlobalRibbonConfig #修改负载均衡算法
在我们文章当中,使用的是全局配置,当然你也可以指定针对单独的服务配置:
#服务名
dt-order-service:ribbon:ConnectTimeout: 1000 #服务请求连接超时时间(毫秒)ReadTimeout: 3000 #服务请求处理超时时间(毫秒)OkToRetryOnAllOperations: true #对超时请求启用重试机制MaxAutoRetriesNextServer: 1 #切换重试实例的最大个数MaxAutoRetries: 1 #切换实例后重试最大次数NFLoadBalancerRuleClassName: com.dt.springcloud.ribbon.config.GlobalRibbonConfig #修改负载均衡算法
总结
好了,以上内容就是今天的输出,后面我们再继续深入研究微服务其他的组件的使用以及原理剖析,创作不易,喜欢的请关注小编CSDN:https://blog.csdn.net/qq_41107231 以及掘金:https://juejin.cn/user/3940246036699848
最新版Spring Cloud Alibaba微服务架构-Ribbon负载均衡篇相关推荐
- 最新版Spring Cloud Alibaba微服务架构-Config配置中心篇
文章目录 前言 一.Config引入背景 1.文件相对分散 2.无法区分环境 3.无法实时更新 4.安全无法保证 二.Config引入配置 1.配置文件格式 1.1 命名空间(Namespace) 1 ...
- 最新版Spring Cloud Alibaba微服务架构-Openfeign服务调用篇
文章目录 前言 一.OpenFeign配置使用 1.引入pom依赖 2.消费端开启Feign服务调用 3.消费端动态代理Service接口 3.消费端测试 二.OpenFeign日志配置 1.全局配置 ...
- 防止内卷和被潜规则,Spring Cloud Alibaba微服务架构实战派(上下册)|35岁程序员那些事
目录 1 写书缘由 2 本书上册核心内容 2.1 Spring Cloud Alibaba基础实战 2.1.1 主要内容 2.1.2 MyBatis-Plus实现多租户架构的核心原理 2.2 分布式服 ...
- Spring Cloud Alibaba微服务架构实战教程—07集成knife4j生成Api文档
前言 通过上一章的学习,我们在smartcar-message子项目中采用MBG插件来生成基础代码,为了加强对代码生成器的使用,我们这一篇,对另外一个子项目smartcar-member进行操作,巩固 ...
- Spring Cloud Alibaba微服务架构实战教程—06让你躺平的敏捷开发
一.前言 在高速发展的今天,微服务通常是把一个大项目根据业务或其他方面划分为了诸多小项目,也就意味着这其中,会产生大量的重复操作,比如上文,建立子模块的步骤就来回进行了7-8次. 假设有几十甚至上百个 ...
- Spring Cloud Alibaba微服务架构实战教程—17分布式缓存下Redis设计
前言 大多数的文章,开头就是告诉你使用redis做缓存,怎么怎么样,而本系列,不打算采用这样无趣的写法,这和直接搬运有什么区别?笔者力求读者能得到更大程度的系统学习,会从为什么使用缓存来给大家进行学习 ...
- 从0到1手把手搭建spring cloud alibaba 微服务大型应用框架(十五) swagger篇 : gateway 集成swagger 与 knife4j实现在线api文档并嵌入到自己项目内
背景 我们日常开发中基本都是协同开发的,当然极个别的项目整体前后端都是一个人开发的,当多人协作时,尤其是前后端人员协同开发时 必然会面临着前端需要了解后端api接口的情况,两个选择,提前设计好文档,然 ...
- Spring Cloud构建微服务架构:分布式服务跟踪(整合zipkin)【Dalston版】
通过上一篇<分布式服务跟踪(整合logstash)>,我们虽然已经能够利用ELK平台提供的收集.存储.搜索等强大功能,对跟踪信息的管理和使用已经变得非常便利.但是,在ELK平台中的数据分析 ...
- Spring Cloud构建微服务架构:分布式服务跟踪(整合logstash)【Dalston版】
通过之前的<入门示例>,我们已经为两个由SpringCloud构建的微服务项目 trace-1和 trace-2引入了Spring Cloud Sleuth的基础模块 spring-clo ...
最新文章
- batch size 越大,学习率也要越大
- linux查看并口设备,如何在LINUX下实现硬件的自动检测(下)
- harmonyos con,鸿蒙HarmonyOS系统中的JS开发框架
- leetcode329. 矩阵中的最长递增路径(dfs)
- RabbitMQ入门学习系列(六) Exchange的Topic类型
- 【C语言】输入一个整数x并判断x是否存在于数组a中
- 蔡高厅老师 - 高等数学阅读笔记 - 15 广义积分和伽马函数 定积分的应用(面积和体积) -(67、68、70、71)
- android 通过短信找回密码,如何通过强力安卓恢复精灵找回丢失的手机短信?
- Jbpm工作流表补数记录
- tarjan算法 转载
- 自己制作一个计时器、倒计时器
- 利用Python爬取一个百度翻译工具(初学爬虫必备)
- APP中使用UI交互设计动效的三个好处
- linux没有cpufreq目录,linux cpufreq framework(1)_概述
- 来自19位科技大亨的励志箴言(绝对值得收藏)
- nao机器人学习笔记3
- OpenCV色彩空间类型
- 如何让子元素居于父元素底部
- java环境变量设置.
- 4-2-1 求e的近似值 (15分)
热门文章
- atom 快速编写html,Atom 编辑器自定义代码段(snippet)
- OpenJudge NOI 1.7 26:字符串最大跨距
- Pell数列(信息学奥赛一本通-T1189)
- 理论基础 —— 排序 —— 快速排序
- Cantor表(洛谷-P1014)
- python中while语句的用法_全面解析Python的While循环语句的使用方法
- sklearn中ValueError: Unknown label type: ‘continuous‘错误解决
- php如何给单选框加js事件,js给元素添加绑定事件
- python二进制移位_python学习特辑——二进制和位运算篇
- c语言条件编译include,7.1编译与预处理-include-c学习 | 时刻需