SpringCloud Alibaba微服务-- Sentinel的使用(保姆级)

一、Sentinel简介

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

1、sentinel的特征

  • 丰富的应用场景: Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等
  • 完备的实时监控: Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况
  • 广泛的开源生态: Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel
    -完善的 SPI 扩展点: Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等

2、sentinel的主要特性
在这里插入图片描述
sentinel的开源生态
在这里插入图片描述
sentinel 的架构图
在这里插入图片描述
3、sentinel的主要优势和特性

  • 轻量级,核心库无多余依赖,性能损耗小
  • 方便接入,开源生态广泛
  • 丰富的流量控制场景
  • 易用的控制台,提供实时监控、机器发现、规则管理等能力
  • 完善的扩展性设计,提供多样化的 SPI 接口,方便用户根据需求给 Sentinel 添加自定义的逻辑

4、sentinel与spring cloud Hystrix 对比

SentinelHystrix
隔离策略信号量隔离线程池隔离/信号量隔离
熔断降级策略基于响应时间或失败比率基于失败比率
实时指标实现滑动窗口滑动窗口(基于 RxJava)
规则配置支持多种数据源支持多种数据源
扩展性多个扩展点插件的形式
基于注解的支持支持支持
限流基于 QPS,支持基于调用关系的限流有限的支持
流量整形支持慢启动、匀速器模式不支持
系统负载保护支持不支持
控制台开箱即用,可配置规则、查看秒级监控、机器发现等不完善
常见框架的适配Servlet、Spring Cloud、Dubbo、gRPC 等Servlet、Spring Cloud Netflix

5、sentinel分为两个部分

  • 核心库(Java 客户端): 不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持
  • 控制台(Dashboard): 基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器

二、Sentinel安装与使用

1、Sentinel控制台的下载
下载地址:https://github.com/alibaba/Sentinel/releases/tag/1.8.3

在这里插入图片描述
我们选择1.8.3版本,直接下载jar包
在这里插入图片描述

放到指定文件夹中
在这里插入图片描述
2、Sentinel控制台的启动

cmd 启动jar包

java -jar sentinel-dashboard-1.8.3.jar

在这里插入图片描述
在这里插入图片描述
2、访问

浏览器输入:localhost:8080
账号密码 默认都是 sentinel
在这里插入图片描述
在这里插入图片描述
3、为服务打开sentinel的监控

引入sentinel依赖

		<dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
            <version>${spring-cloud-alibaba.version}</version>
        </dependency>

专栏的上一篇文章已经为项目引入了sentinel的依赖,以及介绍了feign的使用 感兴趣的可以跳转
手把手教你搭建springcloud alibaba微服务–openfeign

yml文件添加sentinel相关配置

server:
  port: 9090

spring:
  application:
    name: mdx-shop-user
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        namespace: mdx
        group: mdx
    sentinel:
      transport:
        dashboard: localhost:8080 #配置Sentinel dashboard地址
feign:
  sentinel:
    enabled: true

启动user服务并访问user服务的测试接口

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("getOrderNo")
    public String getOrderNo(String userId,String tenantId,HttpServletRequest request){
        return userService.getOrderNo(userId,tenantId,request);
    }
}

浏览器访问
http://localhost:9090/user/getOrderNo?userId=mdx123456&tenantId=123

在这里插入图片描述
然后查看sentinel控制台

发现已经监控到了我们服务的接口
在这里插入图片描述

三、Sentinel的控制规则

1、流控规则

1.1、流控规则的各个属性

  • 资源名: 唯一名称,默认请求路径,表示对该资源进行流控
  • 针对来源: Sentinel可以针对调用者进行限流,填写微服务名,默认default(不区分来源)
  • 阈值类型/单击阈值:
    QPS:(每秒钟的请求数量):当调用该api的QPS达到阈值时,进行限流
    线程数:当调用该线程数达到阈值的时候,进行限流
  • 是否集群:不需要集群
  • 流控模式:
    直接: api达到限流条件时,直接限流
    关联: 当关联的资源达到阈值时,就限流自己
    链路: 只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就进行限流)【api级别的针对来源】
  • 流控效果:
    快速失败: 直接失败,抛异常
    Warm Up: 根据codeFactor(冷加载因子,默认3)的值,从阈值/codeFctor,经过预热时长,才达到设置的QPS阈值
    排队等待: 匀速排队,让请求以匀速的速度通过,阈值类型必须设置为QPS,否则无效

1.2、新增流控规则
在这里插入图片描述

资源名称就是我们的接口访问路径
然后我们一秒一次访问一下接口(正常)
http://localhost:9090/user/getOrderNo?userId=mdx123456&tenantId=123
可以看到正常返回数据
在这里插入图片描述

接下来我们快速请求接口,一秒钟点击多次
发现已经被限流了
在这里插入图片描述

1.3、流控规则–关联流控模式

我们模拟一下流控模式中的关联模式
关联: 当关联的资源达到阈值时,就限流自己,也就是说关联的资源(接口),QPS为1时,一秒内被多次请求的时候,自己的接口就会被限流。

我们在user服务中创建一个关联接口 /user/sentinelB

@GetMapping("sentinelB")
    public String sentinelB(){
        return "我是关联接口";
    }

然后修改一下流控规则
在这里插入图片描述
我们用jmeter模拟一下请求sentinelB接口
一秒3个请求并循环
在这里插入图片描述
在这期间我们访问/user/getOrderNo接口
发现被限流了
在这里插入图片描述

2、@SentinelResource注解的使用

2.1、@SentinelResource的属性

  • value:作用指定资源名称,必填
  • entryType:entry类型,标记流量的方向,指明是出口流量,还是入口流量;取值 IN/OUT ,默认是OUT。非必填
  • blockHandler:处理BlockException的函数名称,函数要求为
    必须是public
    返回类型与原方法一致
    参数类型需要和原方法相匹配,并在最后加上BlockException类型的参数
    默认需和原方法在同一个类中,如果希望使用其他类的函数,可配置blockHandlerClass,并指定blockHandlerClass里面的方法
  • blockHandlerClass:存放blockHandler的类。对应的处理函数必须static修饰,否则无法解析。函数要求为:
    必须是public
    返回类型与原方法一致
    参数类型需要和原方法相匹配,并在最后加上BlockException类型的参数
  • fallback:用于在抛出异常的时候提供fallback处理逻辑。fallback函数可以针对所有类型的异常(除了execptionsToIgnore 里面排除掉的异常类型)进行处理,函数要求为:
    返回类型与原方法一致
    参数类型需要和原方法相匹配,Sentinel 1.6版本之后,也可在方法最后加上Throwable类型的参数
    默认需和原方法在同一个类中,若希望使用其他类的函数,可配置fallbackClass,并指定fallbackClass里面的方法
  • fallbackClass:存放fallback的类。对应的处理函数必须static修饰,否则无法解析,其他要求:同fallback。
  • defaultFallback:用于通用的 fallback 逻辑。默认fallback函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。若同时配置了 fallback 和 defaultFallback,以fallback为准。函数要求:
    返回类型与原方法一致
    方法参数列表为空,或者有一个Throwable类型的参数
    默认需要和原方法在同一个类中,若希望使用其他类的函数,可配置fallbackclass,并指定fallbackClass里面的方法。
  • exceptionsToIgnore:指定排除掉哪些异常。排除的异常不会计入异常统计,也不会进入fallback逻辑,而是原样抛出
  • exceptionsToTrace:需要trace的异常

2.2、按照资源名称的方式限流,并对限流流进行友好处理
我们修改一下/user/getOrderNo接口的代码,增加@SentinelResource注解,并做后续处理
演示代码:

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("getOrderNo")
    @SentinelResource(value = "getOrderNoResource",blockHandler = "getOrderNoBlockHandler",blockHandlerClass = UserController.class)
    public String getOrderNo(String userId, String tenantId, HttpServletRequest request){
        return userService.getOrderNo(userId,tenantId,request);
    }


    /**
     * 限流后续操作方法
     * @param e
     * @return
     */
    public static String getOrderNoBlockHandler(String userId, String tenantId, HttpServletRequest request,BlockException e){
        String msg = "不好意思,前方拥挤,请您稍后再试";
        return msg;
    }

}

其中 getOrderNoResource 为资源名称,getOrderNoBlockHandler 为兜底方法的方法名称,blockHandlerClass = UserController.class 这个是兜底方法所在的类, 与资源方法在同一个类中 这属性可以省去,这里只是演示
注意:返回类型与原方法一致,参数类型需要和原方法相匹配,并在最后加上BlockException类型的参数

然后再修改一下流控规则,把资源名称换成我们注解中的 getOrderNoResource
在这里插入图片描述
快速访问我们的接口,http://localhost:9090/user/getOrderNo?userId=mdx123456&tenantId=123
发现返回的信息已经变成我们兜底方法自定义的返回提示了
在这里插入图片描述

3、熔断规则

3.1、熔断规则的几种策略

  • 慢调用比例 (SLOW_REQUEST_RATIO):选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用。当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断
  • 异常比例 (ERROR_RATIO):当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%
  • 异常数 (ERROR_COUNT):当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断

3.2、新建一个熔断规则
我们先写一个新的接口并且睡眠一秒,使用注解资源名称的形式,并创建自定义兜底方法
方法接口地址 /user/sentinelA

@GetMapping("/sentinelA")
    @SentinelResource(value = "sentinelAResource" , fallback = "sentinelAResource", fallbackClass = UserSentinelResourceHandler.class)
    public String sentinelA(){
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("我是sentinelA");
        return "我是sentinelA";
    }

创建单独的handler类来处理兜底方法

@Component
public class UserSentinelResourceHandler {

    public static String sentinelAResource(Throwable throwable){
    	System.out.println("触发熔断,服务不可用");
        return "触发熔断,服务不可用";
    }
}

接着我们在控制台新建一个熔断规则(使用慢调用比例的策略)
在这里插入图片描述

我们对以上添加的熔断规则解释一下:
在 2 秒的统计时间(统计时长)内,对资源接口的请求数大于 5 (最小请求数),请求响应时间(最大 RT)大于200毫秒的请求占比超过比例阈值 0.1 ,则下一个请求开始触发熔断,熔断时长是 5 秒,也就是 5 秒内,熔断器是打开状态,这期间的请求都会触发熔断,5秒过后熔断器关闭,此时熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。
RT(平均响应时间): 当1s内持续进入5个请求,且对应请求的平均响应时间(秒级)均超过阈值,那么在接下来的时间窗口期内,对该方法的调用都会自动的熔断。注意Sentinel默认统计的RT上限是4900ms,超出此阈值的都会算作4900ms,若需要更改上限可以通过启动配置项-Dcsp.sentinel.statistic.max.rt=xxx来配置

然后我们测试一下
模拟下并发,一秒十个请求循环调用
在这里插入图片描述
我们发现触发阈值之后 已经触发了熔断机制,如下
在这里插入图片描述

3、热点规则

热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的数据,并对其访问进行限制,比如对某个商品id进行限制,或者对某个用户id进行限制

3.1、热点规则属性
参数索引:方法中参数的索引第几个参数
单机阈值:每秒达到单机阈值的数量就会触发兜底方法

4.1、新建一个热点规则
我们先创建一个测试方法,使用注解资源名称的形式,并创建自定义兜底方法

/**
     * 测试centinel热点规则限流
     * @param userId
     * @param shopId
     * @return
     */
    @GetMapping("/hotspot")
    @SentinelResource(value = "hotspotResource" , blockHandler = "hotspotResource", blockHandlerClass = UserSentinelResourceHandler.class)
    public String hotspot(@RequestParam(value = "userId" ,required = false) String userId,
                          @RequestParam(value = "shopId" ,required = false) String shopId){
        System.out.println("我是hotspot");
        return "我是hotspot";
    }

兜底方法

public static String hotspotResource(String userId, String shopId,BlockException blockException){
        System.out.println("您被认为恶意访问,触发热点限流");
        return "您被认为恶意访问,触发热点限流";
    }

然后我们在控制台新建热点规则
在这里插入图片描述
其中参数索引 0 代表的就是userId这个参数
我们访问一下接口
先访问带shopId的(一秒内多次访问) http://localhost:9090/user/hotspot?shopId=4
正常返回
在这里插入图片描述
再访问下带userId参数的(一秒内多次访问) http://localhost:9090/user/hotspot?userId=4
返回降级函数的内容
在这里插入图片描述

4、系统规则

系统保护规则是从应用级别的入口流量进行控制,从单台机器的 load、CPU 使用率、平均 RT、入口 QPS 和并发线程数等几个维度监控应用指标,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性

如果配置了系统规则,所有的接口都会被限流

这里系统规则就不演示了,关于sentinel还有很多规则,策略和属性,大家有兴趣可以自行研究下。

关于sentinel的使用篇就到这里了。

创作不易,点个赞吧👍

最后的最后送大家一句话

白驹过隙,沧海桑田

与君共勉

上一篇文章
springcloud alibaba微服务 – openfeign的使用(保姆级)

下一篇文章
springcloud alibaba – seata原理和使用

文末送福利啦~

1、Java(SE、JVM)、算法数据结构、数据库(Mysql、redis)、Maven、Netty、RocketMq、Zookeeper、多线程、IO、SSM、Git、Linux、Docker、Web前端相关学习笔记
2、2023最新BATJ大厂面试题集
3、本教程项目源码
领取方式:关注下方公主号,回复:【笔记】、【面试】、【mdx-shop】获取相关福利。

文章持续更新,可以关注下方公众号或者微信搜一搜「 最后一支迷迭香 」获取项目源码、干货笔记、面试题集,第一时间阅读,获取更完整的链路资料。

  • 59
    点赞
  • 95
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论
spring-cloud-starter-alibaba-sentinel是一款用于微服务架构中实现流量控制、熔断降、系统负载保护等功能的API库。 首先,它可以实现流量控制,通过设置限流规则,对微服务进行限制,避免大量请求进入服务,导致服务不可用或资源耗尽。可以设置QPS、线程数、并发数等限制条件,对请求进行控制,保障系统的稳定性。 其次,它还支持熔断降功能。当微服务出现异常或超时时,它会根据预设的熔断规则,将服务降,避免故障的扩散。可以通过设置异常比例、异常数等规则,对服务进行自动降,保障系统的可用性。 另外,它还支持系统负载保护功能。通过设置系统负载的阈值,当系统负载超过一定限制时,它会自动出发保护机制,拒绝服务请求,保护系统免受过载的影响。可以设置CPU使用率、内存使用率等指标来判断系统负载情况,保持系统的稳定运行。 此外,spring-cloud-starter-alibaba-sentinel还提供了实时监控、统计和报警功能,可以通过可视化的控制台查看服务的运行状态和性能指标,及时发现问题并进行相应的调整和优化。 总之,spring-cloud-starter-alibaba-sentinel是一款功能强大的API库,可以帮助开发人员在微服务架构中实现流量控制、熔断降、系统负载保护等功能,确保系统的稳定性和可用性。它可以有效地保护系统不受高流量、异常情况和系统负载的影响,提高系统的弹性和可扩展性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

最后一支迷迭香

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值