Sentinel的线程隔离和熔断降级

上一节整理了Sentinel的限流,限流可以降低微服务的负载,避免因为高并发而故障,进而传递给其他相关服务而引发服务雪崩。以上仅为避免服务故障,而当某个服务真正故障时,如何处理才能防止服务雪崩? ⇒ Sentinel支持隔离和降级两种方案

文章目录

  • 1、线程隔离和熔断降级
  • 2、Feign整合Sentinel
  • 3、FallbackFactory代码逻辑
  • 4、线程隔离
  • 5、Sentinel熔断的实现原理
  • 6、熔断策略--慢调用
  • 7、熔断策略--异常比例、异常数

1、线程隔离和熔断降级

采用线程隔离,即舱壁模式:

在这里插入图片描述

  • 业务1:服务A到服务B,限制10线程数
  • 业务2:服务A到服务C,限制10线程数

此时,服务C故障,最大损失10个线程,不会长期占用其他线程,如此,服务A到服务B仍可正常访问,阻止了故障的传递。

在这里插入图片描述

熔断降级,即当请求的失败比例超过阈值时,熔断器阻断服务A到服务D的请求,以后服务A到服务D的请求过来就会直接失败,它没压根机会去访问,也就不会导致资源耗尽,也就不会发生故障传递。

可以看到,不管是线程隔离还是熔断降级,都是对服务调用方的保护,别因为别的服务故障而拖垮自己。

2、Feign整合Sentinel

SpringCloud中,微服务调用都是通过Feign来实现的,因此做客户端保护必须整合Feign和Sentinel

  • 修改服务调用方的application.yaml文件,开启Feign的Sentinel功能
feign:sentinel:    enabled: true # 开启Feign的Sentinel功能
  • 给FeignClient编写失败后的降级逻辑(被阻断了,走另一条路,比如返回msg调用xxService失败)
方式一:FallbackClass,不能对远程调用的异常做处理
方式二:FallbackFactory,可以对远程调用的异常做处理,常选这种

3、FallbackFactory代码逻辑

这是未处理前,feign处理的接口:

@FeignClient(value = "userservice")
public interface UserClient {@GetMapping("/user/{id}")User findById(@PathVariable("id") Long id);
}
  • 在feing-api项目中定义类,实现FallbackFactory接口,且FallbackFactory的泛型中即为关联接口的类型
@Slf4j
public class UserClientFallbackFactory implements FallbackFactory<UserClient> {   //泛型中指定关联的接口的类型@Overridepublic UserClient create(Throwable throwable) {// 创建UserClient接口实现类(匿名内部类),实现其中的方法,编写失败降级的处理逻辑return new UserClient() {@Overridepublic User findById(Long id) {// 记录异常信息log.error("查询用户异常", throwable);// 根据业务需求返回默认的数据,这里是空用户return new User();}};}
}
  • 在模块的配置类DefaultFeignConfiguration中将UserClientFallbackFactory注册为一个Bean:
public class DefaultFeignConfiguration {//new个对象返回@Beanpublic UserClientFallbackFactory userClientFallbackFactory(){return new UserClientFallbackFactory();}
}
  • 在feing-api项目中的UserClient接口中用fallbackFactory属性,使用UserClientFallbackFactory
@FeignClient(value = "userservice", fallbackFactory = UserClientFallbackFactory.class)
public interface UserClient {@GetMapping("/user/{id}")User findById(@PathVariable("id") Long id);
}
  • 重启服务,在Sentinel簇点链路中可以看到被远程调用的服务

在这里插入图片描述

到此,Feign整合Sentinel成功。也可再看下降级处理的效果(停掉被调用服务):

在这里插入图片描述
在这里插入图片描述

4、线程隔离

实现线程隔离有两种方式:

  • 线程池隔离
  • 信号量隔离(Sentinel默认采用)

基于信号量即这个资源请求能用的线程就10个,有个计数器,用一个少一个,请求完后还回去,用完后面的请求就没得用了,以达到舱壁隔离的效果。
在这里插入图片描述

两种方式的优缺点:

  • 基于计数器模式,简单,开销小
  • 基于线程池模式,有额外开销,但隔离控制更强

在这里插入图片描述
Sentinel中的配置示例如下:

在这里插入图片描述

  • QPS:就是每秒的请求数
  • 线程数:是该资源能使用用的tomcat线程数的最大值。也就是通过限制线程数量,实现舱壁模式
需求:给 UserClient的查询用户接口设置流控规则,线程数不能超过 2
  • Sentinel中添加流控规则,阈值类型选择线程数

在这里插入图片描述

  • 启动Jmeter,对/order/101发起测试

在这里插入图片描述

  • 查看结果数,10个请求,8个返回结果user为null且控制台输出报错日志(请求不会失败,因为上面已经做了降级的逻辑处理)

在这里插入图片描述

5、Sentinel熔断的实现原理

由断路器统计服务调用的异常比例、慢请求比例,如果超出阈值则会熔断该服务。即拦截访问该服务的一切请求;而当服务恢复时,断路器才会放行访问该服务的请求。实现思路如下:

在这里插入图片描述

  • 断路器处于closed时,一切请求都不被拦截,且会被统计异常和慢的比例
  • 当比例达到失败阈值,断路器open,所有请求一过来就快速失败
  • 当熔断时间结束,切换好半开放状态,即Half-Open
  • Half-Open状态会尝试放行一些请求,如果依旧失败,则回到Open状态继续拦截,如果成功,则回到Closed状态

6、熔断策略–慢调用

达到某个阈值时,触发熔断,这个就是断路器的熔断策略,分为这三种:慢调用、异常比例、异常数

慢调用:业务的响应时长(RT)大于指定时长的请求认定为慢调用请求。在指定时间内,如果请求数量超过设定的最小数量,慢调用比例大于设定的阈值,则触发熔断。

关于慢调用,即正常蹲坑6分钟,你蹲一小时,半天不释放资源,自然会影响到其他请求。

在这里插入图片描述
以上这个Sentinel配置,即:

- RT超过500ms的调用是慢调用
- 统计最近10000ms内的请求
- 如果请求量超过10次,并且慢调用比例不低于0.5,则触发熔断
- 熔断时长为5秒,然后进入half-open状态,放行一次请求做测试

接下来完成一个实际例子:

需求:
给 UserClient的查询用户接口设置降级规则,慢调用的RT阈值为50ms,统计时间为1秒,最小请求数量为5,失败阈值比例为0.4,熔断时长为5

为了触发慢调用规则,这里修改UserService中的业务,使用休眠来模拟慢调用:

在这里插入图片描述

开始演示:
  • 配置Sentinel降级规则

在这里插入图片描述

  • 狂刷/order/101接口(或者Ctrl+R),/order/101调用的user id就是1,即可触发熔断

在这里插入图片描述

  • 此时访问其他用户,也返回空,因为阻断器open,直接挡回去了

在这里插入图片描述

  • 估摸着5s过去了,阻断器进入到了Half-Open,再重新请求,可以看到正常返回了,当然此时熔断器变为Closed状态

在这里插入图片描述

7、熔断策略–异常比例、异常数

一定时间内的请求,异常请求所占的比例达到设定的比例阈值,或者异常请求的数量达到了设定的数量阈值,即熔断。

在这里插入图片描述
此配置即统计最近1000ms内的请求,如果请求量超过10次,并且异常比例不低于0.4,则触发熔断,熔断时长为5秒。然后进入half-open状态,放行一次请求做测试。


在这里插入图片描述
此配置即统计最近1000ms内的请求,如果请求量超过10次,并且异常数不低于2个,就触发熔断,熔断时长为5秒。然后进入half-open状态,放行一次请求做测试。

需求:
给 UserClient的查询用户接口设置降级规则,统计时间为1秒,最小请求数量为5,失败阈值比例为0.4,熔断时长为5s

这里手动抛异常模拟异常的发生:

在这里插入图片描述

  • 配置降级规则

在这里插入图片描述

  • 刷/order/102,查uid为2的用户,达到异常比例来触发熔断

在这里插入图片描述

  • 然后再访问/order/103,此时103立即失败(被阻断了,所以耗时极小,这里只有7ms)

在这里插入图片描述

  • 等过了阻断器open的时间,再访问就正常了

在这里插入图片描述

熔断策略小结:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/28661.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

手写IOC

IOC原理(手写IOC) Spring框架的IOC是基于反射机制实现的。 反射回顾 Java反射机制是在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够知道这个类的所有属性和方法&#xff0c;对于任意一个对象&#xff0c;都能够调用它的任意方法和属性&#xff1b;这种动态获取信息…

【JS】设置滚动属性默认自动滚动到底部(overflow:scroll;)

文章目录 核心代码应用场景 核心代码 设置滚动属性默认自动滚动到底部&#xff1a; // 获取设置了滚动属性的div标签 const div document.getElementById(conversationalDiv); // 设置滚动的顶点坐标为滚动的总高度 div.scrollTop div.scrollHeight;应用场景 场景&#xff…

050、事务设计之Percolator事务模型

Percolator 背景 Bigtable: 大表打散每行到各个节点&#xff0c;每一行作为一个kv。解决的问题 一个事务涉及的行在多个节点&#xff0c;如何用单行对一个事务进行控制&#xff0c;实现原子性。 快照隔离级别&#xff08;snapshot &#xff09; 白色点&#xff1a;代表事务开始…

flask基本用法小白教程+按钮跳转到指定页面+python和pip安装(后附)

一、flask学习教程&#xff1a; 1.1 基本程序&#xff1a; 大家可以在pycharm中复制如下代码&#xff0c;先感受一下flask的基本用法&#xff1a; 点击链接可进入浏览器查看程序运行的结果&#xff0c;在127.0.0.1:5000后面添上/test1/等设定的文字&#xff0c;可查看不同函…

[RocketMQ] Broker CommitLogDispatcher 异步构建ConsumeQueue和IndexFile源码解析 (十四)

CommitLogDispatcherBuildConsumeQueue: 异步构建ConsumerQueue。CommitLogDispatcherBuildIndex: 异步构建IndexFile。 文章目录 1.CommitLogDispatcherBuildConsumeQueue构建ConsumeQueue1.1 putMessagePositionInfo写入消息位置信息1.2 findConsumeQueue查找ConsumeQueue1.2…

flutter开发实战-卡片翻转动画效果Transform+IndexedStack+rotateAnimation

flutter开发实战-实现卡片翻转动画效果 之前开发中遇到了商品卡片翻转&#xff0c;商品正面是商品图片、商品名称&#xff1b;背面是商品价格&#xff0c;需要做卡片翻转动画。 动画实现即&#xff1a;在一段时间内&#xff0c;快速地多次改变UI外观&#xff1b;由于人眼会产生…

单例模式、指令重排序、锁、有序性

今天在回顾单例模式时&#xff0c;我们都知道懒汉式单例中有一种叫做双重检查锁的单例模式。 我们来看下下面的代码有没有问题&#xff1a; 这段代码我们可以看到&#xff0c;即优化了性能&#xff0c;在多线程情况下&#xff0c;如果实例不为空了&#xff0c;则直接返回了。…

[element-ui] el-select,虚拟滚动(vue-virtual-scroll-list)

一、问题描述 表单中某下拉框&#xff0c;由于数据过多&#xff0c;选择的时候会因为数据量过大导致页面卡顿&#xff0c;于是对于el-select进行二次封装&#xff0c;实现虚拟滚动。 二、实现如下&#xff1a; 看起来是加载了全部数据&#xff0c;实际上只加载了自己设定的1…

无需学习Python,一个公式搞定领导想看的大屏

摘要&#xff1a;本文由葡萄城技术团队于CSDN原创并首发。转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。 不要让“做不了”成为数字化转型的障碍 随着数字化的脚步加快&#xff0c;越来越多的企…

Spring Batch之读数据库—JdbcCursorItemReader之自定义PreparedStatementSetter(三十八)

一、自定义PreparedStatementSetter 详情参考我的另一篇博客&#xff1a; Spring Batch之读数据库——JdbcCursorItemReader&#xff08;三十五&#xff09;_人……杰的博客-CSDN博客 二、项目实例 1.项目实例 2.代码实现 BatchMain.java&#xff1a; package com.xj.dem…

制作Visual Studio离线安装包

vs2015之后官网就不提供离线安装包了&#xff0c;使用离线安装包就需要自己手动制作一个&#xff1b; 以vs2019为例&#xff1a; 先去官网下载在线安装器 官网下载地址&#xff1a;Visual Studio 较旧的下载 - 2019、2017、2015 和以前的版本 (microsoft.com) 展开2019的标签…

从小白到大神之路之学习运维第62天--------Ansible自动化运维工具(playbook配置深入了解2.0)

第三阶段基础 时 间&#xff1a;2023年7月17日 参加人&#xff1a;全班人员 内 容&#xff1a; playbook配置深入了解2.0 目录 一、角色 实验案例&#xff1a;&#xff08;安装Mariadb&#xff09; 二、变量 &#xff08;一&#xff09;在playbook中使用自定义变量&#xff1…