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

简介: 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 对比

Sentinel Hystrix
隔离策略 信号量隔离 线程池隔离/信号量隔离
熔断降级策略 基于响应时间或失败比率 基于失败比率
实时指标实现 滑动窗口 滑动窗口(基于 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】获取相关福利。

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

相关文章
|
8月前
|
负载均衡 Dubbo Java
Spring Cloud Alibaba与Spring Cloud区别和联系?
Spring Cloud Alibaba与Spring Cloud区别和联系?
|
9月前
|
人工智能 SpringCloudAlibaba 自然语言处理
SpringCloud Alibaba AI整合DeepSeek落地AI项目实战
在现代软件开发领域,微服务架构因其灵活性、可扩展性和模块化特性而受到广泛欢迎。微服务架构通过将大型应用程序拆分为多个小型、独立的服务,每个服务运行在其独立的进程中,服务与服务间通过轻量级通信机制(通常是HTTP API)进行通信。这种架构模式有助于提升系统的可维护性、可扩展性和开发效率。
3003 2
|
11月前
|
SpringCloudAlibaba 负载均衡 Dubbo
【SpringCloud Alibaba系列】Dubbo高级特性篇
本章我们介绍Dubbo的常用高级特性,包括序列化、地址缓存、超时与重试机制、多版本、负载均衡。集群容错、服务降级等。
1648 7
【SpringCloud Alibaba系列】Dubbo高级特性篇
|
11月前
|
Java Nacos Sentinel
Spring Cloud Alibaba:一站式微服务解决方案
Spring Cloud Alibaba(简称SCA) 是一个基于 Spring Cloud 构建的开源微服务框架,专为解决分布式系统中的服务治理、配置管理、服务发现、消息总线等问题而设计。
2397 13
Spring Cloud Alibaba:一站式微服务解决方案
|
11月前
|
存储 SpringCloudAlibaba Java
【SpringCloud Alibaba系列】一文全面解析Zookeeper安装、常用命令、JavaAPI操作、Watch事件监听、分布式锁、集群搭建、核心理论
一文全面解析Zookeeper安装、常用命令、JavaAPI操作、Watch事件监听、分布式锁、集群搭建、核心理论。
【SpringCloud Alibaba系列】一文全面解析Zookeeper安装、常用命令、JavaAPI操作、Watch事件监听、分布式锁、集群搭建、核心理论
|
11月前
|
SpringCloudAlibaba JavaScript Dubbo
【SpringCloud Alibaba系列】Dubbo dubbo-admin安装教程篇
本文介绍了 Dubbo-Admin 的安装和使用步骤。Dubbo-Admin 是一个前后端分离的项目,前端基于 Vue,后端基于 Spring Boot。安装前需确保开发环境(Windows 10)已安装 JDK、Maven 和 Node.js,并在 Linux CentOS 7 上部署 Zookeeper 作为注册中心。
3307 1
【SpringCloud Alibaba系列】Dubbo dubbo-admin安装教程篇
|
11月前
|
SpringCloudAlibaba Dubbo Java
【SpringCloud Alibaba系列】Dubbo基础入门篇
Dubbo是一款高性能、轻量级的开源Java RPC框架,提供面向接口代理的高性能RPC调用、智能负载均衡、服务自动注册和发现、运行期流量调度、可视化服务治理和运维等功能。
【SpringCloud Alibaba系列】Dubbo基础入门篇
|
10月前
|
人工智能 安全 Java
AI 时代:从 Spring Cloud Alibaba 到 Spring AI Alibaba
本次分享由阿里云智能集团云原生微服务技术负责人李艳林主讲,主题为“AI时代:从Spring Cloud Alibaba到Spring AI Alibaba”。内容涵盖应用架构演进、AI agent框架发展趋势及Spring AI Alibaba的重磅发布。分享介绍了AI原生架构与传统架构的融合,强调了API优先、事件驱动和AI运维的重要性。同时,详细解析了Spring AI Alibaba的三层抽象设计,包括模型支持、工作流智能体编排及生产可用性构建能力,确保安全合规、高效部署与可观测性。最后,结合实际案例展示了如何利用私域数据优化AI应用,提升业务价值。
976 4
|
10月前
|
人工智能 自然语言处理 Java
Spring Cloud Alibaba AI 入门与实践
本文将介绍 Spring Cloud Alibaba AI 的基本概念、主要特性和功能,并演示如何完成一个在线聊天和在线画图的 AI 应用。
2960 8
|
JSON SpringCloudAlibaba Java
Springcloud Alibaba + jdk17+nacos 项目实践
本文基于 `Springcloud Alibaba + JDK17 + Nacos2.x` 介绍了一个微服务项目的搭建过程,包括项目依赖、配置文件、开发实践中的新特性(如文本块、NPE增强、模式匹配)以及常见的问题和解决方案。通过本文,读者可以了解如何高效地搭建和开发微服务项目,并解决一些常见的开发难题。项目代码已上传至 Gitee,欢迎交流学习。
1014 1
Springcloud Alibaba + jdk17+nacos 项目实践

热门文章

最新文章

下一篇
oss云网关配置