Sentinel服务熔断和降级

2023-10-27

还记得我们前所说的服务降级吗,也就是说我们需要在整个微服务调用链路出现问题的时候,及时对服务进行降级,以防止问题进一步恶化。

那么,各位是否有思考过,如果在某一时刻,服务B出现故障(可能就卡在那里了),而这时服务A依然有大量的请求,在调用服务B,那么,由于服务A没办法再短时间内完成处理,新来的请求就会导致线程数不断地增加,这样,CPU的资源很快就会被耗尽。

那么要防止这种情况,就只能进行隔离了,这里我们提两种隔离方案:

  1. 线程池隔离
    线程池隔离实际上就是对每个服务的远程调用单独开放线程池,比如服务A要调用服务B,那么只基于固定数量的线程池,这样即使在短时间内出现大量请求,由于没有线程可以分配,所以就不会导致资源耗尽了。

  1. 信号量隔离
    信号量隔离是使用Semaphore类实现的(如果不了解,可以观看本系列 并发编程篇 视频教程),思想基本上与上面是相同的,也是限定指定的线程数量能够同时进行服务调用,但是它相对于线程池隔离,开销会更小一些,使用效果同样优秀,也支持超时等。
    Sentinel也正是采用的这种方案实现隔离的。

好了,说回我们的熔断和降级,当下游服务因为某种原因变得不可用或响应过慢时,上游服务为了保证自己整体服务的可用性,不再继续调用目标服务而是快速返回或是执行自己的替代方案,这便是服务降级。

整个过程分为三个状态:

  • 关闭:熔断器不工作,所有请求全部该干嘛干嘛。
  • 打开:熔断器工作,所有请求一律降级处理。
  • 半开:尝试进行一下下正常流程,要是还不行继续保持打开状态,否则关闭。

那么我们来看看Sentinel中如何进行熔断和降级操作,打开管理页面,我们可以自由新增熔断规则:

其中,熔断策略有三种模式:

  1. 慢调用比例:如果出现那种半天都处理不完的调用,有可能就是服务出现故障,导致卡顿,这个选项是按照最大响应时间(RT)进行判定,如果一次请求的处理时间超过了指定的RT,那么就被判定为慢调用,在一个统计时长内,如果请求数目大于最小请求数目,并且被判定为慢调用的请求比例已经超过阈值,将触发熔断。经过熔断时长之后,将会进入到半开状态进行试探(这里和Hystrix一致)
    然后修改一下接口的执行,我们模拟一下慢调用:
@RequestMapping("/borrow2/{uid}")
UserBorrowDetail findUserBorrows2(@PathVariable("uid") int uid) throws InterruptedException {
    Thread.sleep(1000);
    return null;
}


重启,然后我们创建一个新的熔断规则:


可以看到,超时直接触发了熔断,进入到阻止页面:

  1. 异常比例:这个与慢调用比例类似,不过这里判断的是出现异常的次数,与上面一样,我们也来进行一些小测试:
@RequestMapping("/borrow2/{uid}")
UserBorrowDetail findUserBorrows2(@PathVariable("uid") int uid) {
    throw new RuntimeException();
}


启动服务器,接着添加我们的熔断规则:


现在我们进行访问,会发现后台疯狂报错,然后就熔断了:
 

  1. 异常数:这个和上面的唯一区别就是,只要达到指定的异常数量,就熔断,这里我们修改一下熔断规则:


    现在我们再次不断访问此接口,可以发现,效果跟之前其实是差不多的,只是判断的策略稍微不同罢了:

那么熔断规则如何设定我们了解了,那么,如何自定义服务降级呢?之前在使用Hystrix的时候,如果出现异常,可以执行我们的替代方案,Sentinel也是可以的。

同样的,我们只需要在@SentinelResource中配置blockHandler参数(那这里跟前面那个方法限流的配置不是一毛一样吗?没错,因为如果添加了@SentinelResource注解,那么这里会进行方法级别细粒度的限制,和之前方法级别限流一样,会在降级之后直接抛出异常,如果不添加则返回默认的限流页面,blockHandler的目的就是处理这种Sentinel机制上的异常,所以这里其实和之前的限流配置是一个道理,因此下面熔断配置也应该对value自定义名称的资源进行配置,才能作用到此方法上):

@RequestMapping("/borrow2/{uid}")
@SentinelResource(value = "findUserBorrows2", blockHandler = "test")
UserBorrowDetail findUserBorrows2(@PathVariable("uid") int uid) {
    throw new RuntimeException();
}

UserBorrowDetail test(int uid, BlockException e){
    return new UserBorrowDetail(new User(), Collections.emptyList());
}

接着我们对进行熔断配置,注意是对我们添加的@SentinelResource中指定名称的findUserBorrows2进行配置:

OK,可以看到熔断之后,服务降级之后的效果:

最后我们来看一下如何让Feign的也支持Sentinel,前面我们使用Hystrix的时候,就可以直接对Feign的每个接口调用单独进行服务降级,而使用Sentinel,也是可以的,首先我们需要在配置文件中开启支持:

feign:
  sentinel:
    enabled: true

之后的步骤其实和之前是一模一样的,首先创建实现类:

@Component
public class UserClientFallback implements UserClient{
    @Override
    public User getUserById(int uid) {
        User user = new User();
        user.setName("我是替代方案");
        return user;
    }
}

然后直接启动就可以了,中途的时候我们吧用户服务全部下掉,可以看到正常使用替代方案:

这样Feign的配置就OK了,那么传统的RestTemplate呢?我们可以使用@SentinelRestTemplate注解实现:

  @Bean
  @LoadBalanced
  @SentinelRestTemplate(blockHandler = "handleException", blockHandlerClass = ExceptionUtil.class,
      fallback = "fallback", fallbackClass = ExceptionUtil.class) //这里同样可以设定fallback等参数
  public RestTemplate restTemplate() {
    return new RestTemplate();
  }

这里就不多做赘述了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Sentinel服务熔断和降级 的相关文章

随机推荐

  • 瑞吉外卖开发梳理及重点知识讲解

    一 项目导读 瑞吉外卖是一个单体架构 整体的业务逻辑也较为简单 如果刚学SpringBoot技术 想要通过项目练手 那这是一个很好的选择 不仅可以练习SpringBoot技术 还可以学习Mybatis Plus Redis 项目部署 服务器
  • 网络基础:子网划分

    目录 一 理论 1 IP地址结构 2 子网掩码 3 网络地址 二 实验 1 中国移动10 0 0 0 8 为32个省分配各自的子网 一 理论 1 IP地址结构 IP地址就是一个唯一标识 是一段网络编码 二进制 IP地址由两部分组成 一部分为
  • XXXXRockey4ND加密狗复制

    一 加密狗复制的前提条件 1 有所使用的软件 2 有所需的原加密狗 3 同型号的加密狗 二 所需环境 1 windows 2 所需加密狗的软件正常安装 三 复制步骤 1 将Rockey4ND加密狗读狗工具中的Hid dll放置在所需加密狗的
  • 测试人员职业发展之路

    在我们开始尝试为大家描述软件测试工作的多种可能性之前 先来看看在现在所知最近代的开发模式中 测试人员还会继续存在吗 因为如果连测试工作本身都不存在了 我们也没必要进行后续的讨论了 很多做测试的朋友问过这样一个问题 现在敏捷开发模式中 自动化
  • Spring Boot 序列化和反序列化

    Spring Boot 开发一个web应用程序时 你可以通过使用嵌入式tomcat jetty Undertow 或者Netty来实现内置http Server 在spring boot中 只需要添加spring boot starter
  • Android 软件测试日志文件抓取

    http zzhhui i sohu com blog view 242248931 htm 1 log文件分类简介 实时打印的主要有 logcat main logcat radio logcat events tcpdump 还有高通平
  • Lodash 一个著名的javascript原生库

    Ldash官网 https lodash com 简介 Lodash是一个内部封装了诸多对字符串 数组 对象等常见的数据类型的处理函数的一套工具库 它使用延迟计算 使得其性能大大提升 延迟计算意味着在我们的链式方法在显示或者隐藏式的valu
  • 全栈之前端

    关注回复 学习交流群 加入 安全开发运维 答疑交流群 原文地址 全栈之前端 1 CSS3必备基础知识学习前面跟随着 WeiyiGeeker 作者 全栈工程师修炼指南 公众号一起学习了前端基础的知识以及HTML标签 属性 事件 字符集系列教程
  • 计算机图形图像知识梳理,计算机图形学知识点总结

    第一章 计算机图形学概论 1 比较计算机图形学与图象处理技术相同点和不同点 Computer Graphics 计算机图形学 和Computer Vision 计算机图像识别 是同一过程的两个方向 Computer Graphics将抽象的
  • Node.js学习笔记--npm命令

    npm命令 本章学习npm的命令 1 基础命令 1 npm v 查看版本 2 npm version 查看所有模块版本 3 npm search 包名搜索 4 npm install i 包安装 5 npm remove r 包移除 6 n
  • 【C进阶】指针(一)

    大家好 我是深鱼 前言 指针的主题 在初阶指针章节已经接触过了 我们知道了指针的概念 1 指针就是个变量 用来存放地址 地址的唯一标识一块内存空间 指针变量 内存单元是由编号的 编号 地址 指针 2 指针 地址 指针变量的大小是固定的4 8
  • Doxygen使用介绍

    Doxygen的主页为http doxygen nl 它的license为GPL 最新发布版本为1 8 17 源代码存放在https github com doxygen doxygen 它支持的语言包括C C Objective C C
  • matlab求解普通函数的导数问题(diff函数的用法)

    目录 一元函数的导数 MATLAB函数语法 应用举例 例1 普通函数求导 例2 复合泛函求导 例3 矩阵函数求导 多元函数的偏导数 MATLAB函数语法 应用举例 例1 求偏导并绘图 例2 三元函数求偏导 一元函数的导数 MATLAB函数语
  • matlab RANSAC拟合二次多项式曲线(详细过程版)

    目录 一 算法概述 二 代码实现 三 结果展示 四 相关链接 一 算法概述 RANSAC是一种鲁棒性较强的拟合算法 可以用于估计数据集中的模型参数 对于拟合二次多项式曲线 RANSAC算法的步骤如下 1 随机选择一小部分数据点 假设它们是符
  • NodeMCU-32S-内部DAC音频输出测试

    NodeMCU 32S 内部DAC音频输出测试 文章目录 NodeMCU 32S 内部DAC音频输出测试 前言 硬件说明 软件编译 测试 ESP32 DAC参考链接 前言 一直想玩玩ESP32的蓝牙音频功能 手上面有一个NodeMCU 32
  • DAY02: 编程入门03- 核心代码解析

    1 Arduino默认提供的两个方法 setup 方法 用于初始化 程序一开始 只运行一次 用于定于引脚为OUTPUT还是INPUT loop 方法 循环不停得执行 用于编写小车移动旋转等一直需要命令的代码 2 小车电机运动的核心方法 定于
  • ESP8266 NodeMCU 擦除闪存执行出厂重置

    在本教程中 我们将了解如何在 Windows Linux 和 MacOS 中使用 esptool py 命令行实用程序擦除 ESP8266 的闪存 并讨论为什么以及何时需要执行此操作 与任何电子设备一样 有时您可能需要将 ESP8266 重
  • 学校报名登记收缴费用小程序开发制作

    报名登记收缴费用小程序 适合培训机构 幼儿园 小学 高中 初中 大学等学校 报名登记小程序 微信扫码登记 手机端登记报名信息 数据发送至管理后台 管理员可查阅数据列表 完成了学生报名信息收集 审核 修改 复审 收费 等多项复杂功能 收费可以
  • 蜣螂优化(DBO)算法附MATLAB代码

    目录 一 蜣螂优化 DBO 算法灵感来源 二 蜣螂优化 DBO 算法设计 三 蜣螂优化 DBO 算法MATLAB部分代码 四 运行结果 蜣螂优化 Dung Beetle Optimizer DBO 算法是2022年11月27日提出的 大家可
  • Sentinel服务熔断和降级

    还记得我们前所说的服务降级吗 也就是说我们需要在整个微服务调用链路出现问题的时候 及时对服务进行降级 以防止问题进一步恶化 那么 各位是否有思考过 如果在某一时刻 服务B出现故障 可能就卡在那里了 而这时服务A依然有大量的请求 在调用服务B