Sentinel

官网:https://sentinelguard.io/zh-cn/index.html
开发文档:https://sentinelguard.io/zh-cn/docs/introduction.html
整合Spring CloudAlibaba(推荐) https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinel
Github详细文档(推荐) https://github.com/alibaba/Sentinel/wiki/介绍
官方控制台说明https://github.com/alibaba/Sentinel/wiki/控制台

要对吞吐量(TPS)、QPS、并发数、响应时间(RT)几个概念做下了解

  1. 响应时间(RT)
      响应时间是指系统对请求作出响应的时间。直观上看,这个指标与人对软件性能的主观感受是非常一致的,因为它完整地记录了整个计算机系统处理请求的时间。由于一个系统通常会提供许多功能,而不同功能的处理逻辑也千差万别,因而不同功能的响应时间也不尽相同,甚至同一功能在不同输入数据的情况下响应时间也不相同。所以,在讨论一个系统的响应时间时,人们通常是指该系统所有功能的平均时间或者所有功能的最大响应时间。当然,往往也需要对每个或每组功能讨论其平均响应时间和最大响应时间。
      对于单机的没有并发操作的应用系统而言,人们普遍认为响应时间是一个合理且准确的性能指标。需要指出的是,响应时间的绝对值并不能直接反映软件的性能的高低,软件性能的高低实际上取决于用户对该响应时间的接受程度。对于一个游戏软件来说,响应时间小于100毫秒应该是不错的,响应时间在1秒左右可能属于勉强可以接受,如果响应时间达到3秒就完全难以接受了。而对于编译系统来说,完整编译一个较大规模软件的源代码可能需要几十分钟甚至更长时间,但这些响应时间对于用户来说都是可以接受的。
  2. 吞吐量(Throughput)
    吞吐量是指系统在单位时间内处理请求的数量。对于无并发的应用系统而言,吞吐量与响应时间成严格的反比关系,实际上此时吞吐量就是响应时间的倒数。前面已经说过,对于单用户的系统,响应时间(或者系统响应时间和应用延迟时间)可以很好地度量系统的性能,但对于并发系统,通常需要用吞吐量作为性能指标。
      对于一个多用户的系统,如果只有一个用户使用时系统的平均响应时间是t,当有你n个用户使用时,每个用户看到的响应时间通常并不是n×t,而往往比n×t小很多(当然,在某些特殊情况下也可能比n×t大,甚至大很多)。这是因为处理每个请求需要用到很多资源,由于每个请求的处理过程中有许多不走难以并发执行,这导致在具体的一个时间点,所占资源往往并不多。也就是说在处理单个请求时,在每个时间点都可能有许多资源被闲置,当处理多个请求时,如果资源配置合理,每个用户看到的平均响应时间并不随用户数的增加而线性增加。实际上,不同系统的平均响应时间随用户数增加而增长的速度也不大相同,这也是采用吞吐量来度量并发系统的性能的主要原因。一般而言,吞吐量是一个比较通用的指标,两个具有不同用户数和用户使用模式的系统,如果其最大吞吐量基本一致,则可以判断两个系统的处理能力基本一致。
  3. 并发用户数
    并发用户数是指系统可以同时承载的正常使用系统功能的用户的数量。与吞吐量相比,并发用户数是一个更直观但也更笼统的性能指标。实际上,并发用户数是一个非常不准确的指标,因为用户不同的使用模式会导致不同用户在单位时间发出不同数量的请求。一网站系统为例,假设用户只有注册后才能使用,但注册用户并不是每时每刻都在使用该网站,因此具体一个时刻只有部分注册用户同时在线,在线用户就在浏览网站时会花很多时间阅读网站上的信息,因而具体一个时刻只有部分在线用户同时向系统发出请求。这样,对于网站系统我们会有三个关于用户数的统计数字:注册用户数、在线用户数和同时发请求用户数。由于注册用户可能长时间不登陆网站,使用注册用户数作为性能指标会造成很大的误差。而在线用户数和同事发请求用户数都可以作为性能指标。相比而言,以在线用户作为性能指标更直观些,而以同时发请求用户数作为性能指标更准确些。
  4. QPS每秒查询率(Query Per Second)
    每秒查询率QPS是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准,在因特网上,作为域名系统服务器的机器的性能经常用每秒查询率来衡量。对应fetches/sec,即每秒的响应请求数,也即是最大吞吐能力。 (看来是类似于TPS,只是应用于特定场景的吞吐量)

一、Sentinel简介

1、什么是Sentinel

Sentinel是阿里开源的项目,提供了流量控制、熔断降级、系统负载保护等多个维度来保障服务之间的稳定性。
官网:https://github.com/alibaba/Sentinel/wiki
2012年,Sentinel诞生于阿里巴巴,其主要目标是流量控制。2013-2017年,Sentinel迅速发展,并成为阿里巴巴所有微服务的基本组成部分。 它已在6000多个应用程序中使用,涵盖了几乎所有核心电子商务场景。2018年,Sentinel演变为一个开源项目。2020年,Sentinel Golang发布。

2、Sentinel 特征

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

895e1da1947f697662e0ea38c1222605.png
Sentinel主要特性:
20200529140109886.png
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由流量控制流量整形熔断降级系统自适应过载保护热点流量防护等多个维度来帮助开发者保障微服务的稳定性。
image-20230322154257487.png

二、Sentinel安装

1、下载Jar文件 https://github.com/alibaba/Sentinel/releases 目前最新版本1.8.5 上传至/usr/local下
image-20230322154609115.png
2、启动控制台,执行 Java 命令 java -jar sentinel-dashboard.jar完成 Sentinel 控制台的启动。 控制台默认的监听端口为 8080。Sentinel 控制台使用 Spring Boot 编程模型开发,如果需要指定其他端口,请使用 Spring Boot 容器配置的标准方式
使用如下命令启动控制台:

  1. java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar

其中 -Dserver.port=8080 用于指定 Sentinel 控制台端口为 8080
image-20230322155008768.png
3、访问 http://localhost:8080 页面 账户密码: sentinel / sentinel
image-20230322155123828.png

三、SpringCloud整合Sentinel

1、引入Sentinel

  1. <dependency>
  2. <groupId>com.alibaba.cloud</groupId>
  3. <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
  4. </dependency>

2、添加配置

  1. spring:
  2. cloud:
  3. sentinel:
  4. transport:
  5. port: 8719 # 默认8719端口,假如被占用了会自动从8719端口+1进行扫描,直到找到未被占用的 端口
  6. dashboard: localhost:8080 #配置Sentin dashboard地址(改成自己的服务器ip地址,本地用localhost‍)

3、调用接口,查看控制台

注意:请确保 Sentinel 控制台所在的机器时间与自己应用的机器时间保持一致,否则会导致拉不到实时的监控数据。
image-20230322161132560.png

四、控制台-流控模式

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

1、流控模式——直接

当QPS每秒请求次数超过设定的单机阈值后,直接引发流控效果。

  1. 例子:
  2. 资源名:/server
  3. 设置阈值类型为:QPS
  4. 单机阈值:1
  5. 流控模式:直接
  6. 流控效果:快速失败
  7. 效果:
  8. 当请求/server接口,每秒超过1次后,接口直接报错“ Blocked by Sentinel (flow limiting)

image-20230322170440373.png

2、流控模式——关联

当关联的资源达到阈值时,就限流自己。(通俗理解:关联的资源惹事,自己坐牢)
使用场景

  • 一个优先级较高,一个优先级较低。
  • 两个有竞争关系的资源,例如下述中的查询与更新,要优先让更新操作执行。

比如: 下单接口和查询订单接口,当我们对查询接口设置了流控规则并关联了下单接口,当下单接口的请求数量达到阈值时,就会对查询接口进行限流,这样就能保证下单接口的安全性。

  1. 例子:
  2. 资源名:/serverA
  3. 设置阈值类型为:QPS
  4. 单机阈值:1
  5. 流控模式:关联
  6. 关联资源:/serverB
  7. 流控效果:快速失败
  8. 效果:
  9. 当请求/serverB接口,每秒超过1次后,快速请求/serverA接口直接报错“ Blocked by Sentinel (flow limiting)
  10. 单独请求/serverA接口,不受QPS阈值限制
  11. 单独请求/serverB接口,不受QPS阈值限制

image-20230322172215891.png

3、流控模式——链路

对调用链路的入口进行限流,Sentinel可以对方法进行限流,通过注解 @SentinelResource 对方法进行标记
当接口A和接口B,都调用通一个方法,可以设置关联接口A进行限流,而接口B不受限制。

  1. 例子:
  2. 接口A,订单支付功能。
  3. 接口B,添加购物车功能。
  4. 方法:查询商品信息
  5. 效果:
  6. 保证订单支付功能,当添加购物车阈值大于1时,进行限流。
  7. 当访问/order/shoppingCart,频率超过1QPS,进行限制。/order/pay不受限制。

接口

  1. @RestController
  2. public class Controller {
  3. @Autowired
  4. private OrderQueryService orderQueryService;
  5. /**
  6. * 订单支付
  7. *
  8. * @return
  9. */
  10. @GetMapping("/order/pay")
  11. public String orderPay() {
  12. return orderQueryService.orderQuery();
  13. }
  14. /**
  15. * 添加购物车
  16. *
  17. * @return
  18. */
  19. @GetMapping("/order/shoppingCart")
  20. public String orderShoppingCart() {
  21. return orderQueryService.orderQuery();
  22. }
  23. }

方法

  1. @Service
  2. public class OrderQueryService {
  3. @SentinelResource("orderQuery")
  4. public String orderQuery() {
  5. return "查询订单成功!" + System.currentTimeMillis();
  6. }
  7. }

配置
这是因为Sentinel 的 CommonFilter 的 web-context-unify 参数默认为true,表示要将调用链路收敛,会导致链路流控效果无效。 我们需要将这个参数设置成true才能取消链路收敛才会生效。

  1. # 默认为true,表示将调用链路收敛,会导致链路流控效果无效,需要改成false
  2. spring.cloud.sentinel.web-context-unify=false

image-20230327154714344.png

五、控制台-流控效果

1、流控效果——快速失败

快速失败RuleConstant.CONTROL_BEHAVIOR_DEFAULT)方式是默认的流量控制方式,当QPS超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出FlowException。这种方式适用于对系统处理能力确切已知的情况下,比如通过压测确定了系统的准确水位时。
返回 Blocked by Sentinel (flow limiting)
image-20230327154714344.png

2、流控效果——Warm Up

  1. 公式:阈值除以codeFactor(默认值为3),经过预热时长后达到阈值。
  2. 默认 coldFactor 为 3,即请求 QPS 从 threshold / 3 开始,经预热时长逐渐升至设定的 QPS 阈值。官方说明
    image-20230327160421824.png
  3. Warm up 配置
    阈值设置为 10 ,预热时长设置为 5 秒。系统初始化的阈值为 10/3,经过经过了 5 秒后阈值慢慢升高至 10。
    image-20230327161701483.png
  4. 使用场景
    秒杀系统在开启的瞬间,会有很多流量上来,可能导致系统崩溃,预热的方式就是为了保护系统,可以慢慢的把请求的流量放进来,慢慢的把初始化阈值 QPS/3 增长到指定设置的阈值

    3、流控效果——排队等待

    匀速排队(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。
    这种方式主要用于处理间隔性突发的流量,例如消息队列。想象一下这样的场景,在某一秒有大量的请求到来,而接下来的几秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理这些请求,而不是在第一秒直接拒绝多余的请求。

    注意:匀速排队模式暂时不支持 QPS > 1000 的场景。

例如下图中,每秒只接受1个请求,多余的请求排队,如果排队的请求超出500毫秒,则失效。
image-20230327162054128.png

六、控制台-熔断策略

官方熔断降级

1、熔断策略——慢调用比列

  • 慢调用比例 (SLOW_REQUEST_RATIO):选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用。当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。

    1. 例子:
    2. 最大响应时间300,熔断时长10秒,统计时长1秒,比例阈值0.1(10%),最小请求数5


    image-20230327164936154.png d78dca81d52b4255a8bdf4fa17b1b40a.png

    2、熔断策略——异常比例

  • 异常比例 (ERROR_RATIO):当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%。

注意:异常降级仅针对业务异常,对 Sentinel 限流降级本身的异常(BlockException)不生效。
image-20230327165522508.png
aa53538f26df4e2696489b428b6821dc.png

3、熔断策略——异常数

  • 异常数 (ERROR_COUNT):当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。

image-20230327165803212.png
4b39c0f4bfdb4a3daa96339f9f56ca92.png

七、控制台-热点规则

何为热点?热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据,并对其访问进行限制。比如:

  • 商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制
  • 用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制

热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。官网
注意:参数索引:0为第一个参数、以此类推,只要访问接口携带第一个参数即可热点限流。

  1. 例子:
  2. 请求参数1String orderId
  3. 请求参数2String userName
  4. 当前携带orderId参数时,设置热点限制。
  5. 效果:
  6. 访问 http://localhost:9090/order/queryParam?orderId=1&userName=2 阈值超过1则限流
  7. 访问 http://localhost:9090/order/queryParam?orderId=1 阈值超过1则限流
  8. 访问 http://localhost:9090/order/queryParam?userName=2 不限流

image-20230327172501347.png
使用注解@SentinelResourc标注需要热点的方法

  1. /**
  2. * 使用@SentinelResource标签开启热点参数限流功能
  3. * @SentinelResource(value)对应Sentinel控制台-热点规则-资源名
  4. * @SentinelResource(blockHandeler)指定热点限流生效后的处理函数
  5. */
  6. @GetMapping("/order/queryParam")
  7. @SentinelResource(value = "/order/queryParam", blockHandler = "deal_testHotKey")
  8. public String orderQueryParam(@RequestParam(value = "orderId", required = false) String orderId,
  9. @RequestParam(value = "userName", required = false) String userName) throws InterruptedException {
  10. System.out.println("请求参数orderId:" + orderId + "userName:" + userName);
  11. return "订单查询成功!";
  12. }
  13. public String deal_testHotKey(String orderId, String userName, BlockException exception){
  14. // sentinel默认的提示为:Blocked by Sentinel(flow limiting),这里可以自定义修改
  15. return "-------------------- 自定义返回内容 --------------------------";
  16. }

参数额外项

  1. 例子:
  2. 当第一个参数的参数为 String类型的1时,单独的阈值为10QPS
  3. 效果:
  4. 访问 http://localhost:9090/order/queryParam?orderId=1&userName=2 阈值超过10则限流
  5. 访问 http://localhost:9090/order/queryParam?orderId=22 阈值超过1则限流

image-20230327174807889.png

八、控制台-系统规则

  1. 系统保护规则是从应用级别的入口流量进行控制,从单台机器的 loadCPU 使用率、平均 RT、入口 QPS 和并发线程数等几个维度监控应用指标,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。<br /> 系统保护规则是应用整体维度的,而不是资源维度的,并且**仅对入口流量生效**。入口流量指的是进入应用的流量(`EntryType.IN`),比如 Web 服务或 Dubbo 服务端接收的请求,都属于入口流量。<br />系统规则支持以下的模式:
  • Load 自适应(仅对 Linux/Unix-like 机器生效):系统的 load1 作为启发指标,进行自适应系统保护。当系统 load1 超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR 阶段)。系统容量由系统的 maxQps * minRt 估算得出。设定参考值一般是 CPU cores * 2.5
  • CPU usage(1.5.0+ 版本):当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0),比较灵敏。
  • 平均 RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。
  • 并发线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。
  • 入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。
    image-20230327180434421.png

    九、控制台-授权规则

    很多时候,我们需要根据调用来源来判断该次请求是否允许放行,这时候可以使用 Sentinel 的来源访问控制(黑白名单控制)的功能。来源访问控制根据资源的请求来源(origin)限制资源是否通过,若配置白名单则只有请求来源位于白名单内时才可通过;若配置黑名单则请求来源位于黑名单时不通过,其余的请求通过。
    来源访问控制规则(AuthorityRule)非常简单,主要有以下配置项:

  • resource:资源名,即限流规则的作用对象。

  • limitApp:对应的黑名单/白名单,不同 origin 用 , 分隔,如 appA,appB
  • strategy:限制模式,AUTHORITY_WHITE 为白名单模式,AUTHORITY_BLACK 为黑名单模式,默认为白名单模式。

    十、@SentinelResource 注解

    Sentinel 支持通过 @SentinelResource 注解定义资源并配置 blockHandlerfallback 函数来进行限流之后的处理。@SentinelResource 注解是 Sentinel 提供的最重要的注解之一,它还包含了多个属性,如下表:
属性 说明 必填与否 使用要求
value 用于指定资源的名称 必填 -
entryType entry 类型 可选项(默认为 EntryType.OUT) -
blockHandler 服务限流后会抛出 BlockException 异常,而 blockHandler 则是用来指定一个函数来处理 BlockException 异常的。 简单点说,该属性用于指定服务限流后的后续处理逻辑。 可选项 1、blockHandler 函数访问范围需要是 public2、返回类型需要与原方法相匹配;
3、参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException
4、blockHandler 函数默认需要和原方法在同一个类中,若希望使用其他类的函数,则可以指定 blockHandler 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
blockHandlerClass 若 blockHandler 函数与原方法不在同一个类中,则需要使用该属性指定 blockHandler 函数所在的类。 可选项 1、不能单独使用,必须与 blockHandler 属性配合使用;
2、该属性指定的类中的 blockHandler 函数必须为 static 函数,否则无法解析。
fallback 用于在抛出异常(包括 BlockException)时,提供 fallback 处理逻辑。 fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。 可选项 1、返回值类型必须与原函数返回值类型一致
2、方法参数列表需要和原函数一致,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常
3、fallback 函数默认需要和原方法在同一个类中,若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
fallbackClass 若 fallback 函数与原方法不在同一个类中,则需要使用该属性指定 blockHandler 函数所在的类。 可选项 1、不能单独使用,必须与 fallback 或 defaultFallback 属性配合使用
2、该属性指定的类中的 fallback 函数必须为 static 函数,否则无法解析。
defaultFallback 默认的 fallback 函数名称,通常用于通用的 fallback 逻辑(即可以用于很多服务或方法)。 默认 fallback 函数可以针对所以类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。 可选项 1、返回值类型必须与原函数返回值类型一致
2、方法参数列表需要为空,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常;
3、defaultFallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
exceptionsToIgnore 用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。 可选项 -

限流后抛出异常处理

  1. /**
  2. * 使用@SentinelResource标签开启热点参数限流功能
  3. * @SentinelResource(value)对应Sentinel控制台-热点规则-资源名
  4. * @SentinelResource(blockHandeler)指定热点限流生效后的处理函数
  5. */
  6. @GetMapping("/order/queryParam")
  7. @SentinelResource(value = "/order/queryParam", blockHandler = "deal_testHotKey")
  8. public String orderQueryParam(@RequestParam(value = "orderId", required = false) String orderId,
  9. @RequestParam(value = "userName", required = false) String userName) {
  10. System.out.println("请求参数orderId:" + orderId + "userName:" + userName);
  11. return "订单查询成功!";
  12. }
  13. public String deal_testHotKey(String orderId, String userName, BlockException exception){
  14. // sentinel默认的提示为:Blocked by Sentinel(flow limiting),这里可以自定义修改
  15. return "-------------------- 自定义返回内容 --------------------------";
  16. }

全局的兜底方法

  1. public class LimitHandler {
  2. public static String handlerException(String connect,BlockException blockException) {
  3. return "服务降级。。。。。";
  4. }
  5. }
  6. @GetMapping("/limit1")
  7. @SentinelResource(value = "/limit1", blockHandlerClass = LimitHandler.class, blockHandler = "handlerException")
  8. public String limit1(String connect) {
  9. return "订单查询成功!" + connect;
  10. }

异常后处理

  1. @GetMapping("/errorIndex")
  2. @SentinelResource(value = "/errorIndex", fallback = "errorBlockHandler")
  3. public String error(String connect) {
  4. int a = 1 / 0;
  5. return "订单查询成功!" + connect;
  6. }
  7. public String errorBlockHandler(String connect) {
  8. return "-------------------- 服务发生异常 --------------------------";
  9. }

注意: 同时配置blockHandler和fallback,只会进入 blockHandler 处理逻辑。

十一、配合OpenFeign使用

1、添加pom

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-openfeign</artifactId>
  4. </dependency>

2、yml

  1. #激活Sentinel对Feign的支持
  2. feign:
  3. sentinel:
  4. enabled: true

3、主启动类上添加**@EnableFeignClients**
4、接口编写

  1. @Component
  2. @FeignClient(value = "ProviderServer", fallback = FeignFallBack.class)
  3. public interface ProviderFeign {
  4. // 业务类直接调用该接口即可
  5. @GetMapping("/provider/get/{id}")
  6. public String get(@PathVariable("id") Integer id);
  7. }
  8. @Component
  9. public class FeignFallBack implements ProviderFeign {
  10. @Override
  11. public String get(Integer id) {
  12. return "降级返回";
  13. }
  14. }

十二、Sentinel持久化

sentinel持久化有多种方式,可以整合nacos、还可以修改源码。

1、pom

  1. <!-- SpringCloud ailibaba sentinel-datasource-nacos 持久化需要用到-->
  2. <dependency>
  3. <groupId>com.alibaba.csp</groupId>
  4. <artifactId>sentinel-datasource-nacos</artifactId>
  5. </dependency>

2、yml

  1. server:
  2. port: 8401
  3. spring:
  4. application:
  5. name: cloudalibaba-sentinel-service
  6. cloud:
  7. sentinel:
  8. transport:
  9. dashboard: 127.0.0.1:8080
  10. port: 8719
  11. datasource:
  12. dsl: # 名称随意
  13. nacos:
  14. server-addr: 192.168.100.108:8848 # nacos地址
  15. dataId: cloudalibaba-sentinel-service #nacos配置的dataId
  16. groupId: DEFAULT_GROUP # nacos配置的groupId
  17. data_type: json # 配置文件类型
  18. rule-type: flow #规则类型
  19. management:
  20. endpoints:
  21. web:
  22. exposure:
  23. include: "*"
  24. feign:
  25. sentinel:
  26. enabled: true #激活Sentinel 对Feign的支持

3、nacos添加配置
1540879-20210408225457242-1374977624.png

  1. [
  2. {
  3. "resource":"/retaLimit/byUrl", // 资源名
  4. "limitApp":"default", //来源应用
  5. "grade":1, //阈值类型,0 表示线程数,1表示QPS
  6. "count":1, // 单机阈值
  7. "strategy":0, // 流控模式, 0表示直接,1表示关联, 2表示链路
  8. "controlBehavior":0, //流控效果, 0表示快速失败,1表示 Warm Up, 2表示排队等待
  9. "clusterMode":false //是否集群
  10. }
  11. ]