Sentinel的初步学习(1)

Sentinel的初步学习(2)https://blog.csdn.net/BinXNoob/article/details/106432883

Sentinel实现熔断限流》》》》》Hystrix

https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D

下载地址:https://github.com/alibaba/Sentinel/releases

1.运行Sentinel

下载完成后,确保jdk是1.8及其以上,8080端口没有被占用

进入cmd,输入 java -jar sentinel-dashboard-1.7.2.jar

如图:

Sentinel的初步学习(1)_第1张图片

出现这个界面就是启动成功

再去访问http://localhost:8080/ , 账号密码均是sentinel

就可以进入sentinel控制平台

2.初始化演示

1.启动Nacos8848

2.新建项目(8401端口)

POM

需要引入sentinel的依赖以及后续持久化依赖

 <dependency>
            <groupId>com.xwb.springcloudgroupId>
            <artifactId>cloud-api-commonsartifactId>
            <version>1.0-SNAPSHOTversion>
        dependency>

        
        <dependency>
            <groupId>com.alibaba.cloudgroupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
        dependency>
        
        <dependency>
            <groupId>com.alibaba.cspgroupId>
            <artifactId>sentinel-datasource-nacosartifactId>
        dependency>
        
        <dependency>
            <groupId>com.alibaba.cloudgroupId>
            <artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-openfeignartifactId>
        dependency>

        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-actuatorartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-devtoolsartifactId>
            <scope>runtimescope>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>

什么是懒加载

启动8401端口,这时在sentinel的控制台中并没有看到我们的8401端口的信息

这是sentinel是懒加载的原因

我们需要先访问8401端口才可以

访问过后
Sentinel的初步学习(1)_第2张图片

现在可以对我们8401进行实时监控

3.流控规则(流量)和流控效果

我们现在只是拿着我们的rest地址进行控制,也就是资源名

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

Sentinel的初步学习(1)_第3张图片

直接(默认,快速失败)

Sentinel的初步学习(1)_第4张图片

设置好之后,访问8401/TestA连接

在一秒内多次点击出现以下情况

Sentinel的初步学习(1)_第5张图片

表示1s内只允许查询1次,若是超过,直接快速失败,默认报错

这里只是调用模板默认报错信息,如何使用自己的

这里我们应该类似一个fallback的兜底调用方法

关联

当关联的资源达到阈值时, 就限流自己

若A关联的资源B达到阈值,就限流A

我们在sentinel的控制台设置A关联上B

Sentinel的初步学习(1)_第6张图片
然后同时启动A和B
为了方便,这里使用post多并发访问

Sentinel的初步学习(1)_第7张图片

进入collection设置

Sentinel的初步学习(1)_第8张图片

启动并访问A,发现A出现报错

Sentinel的初步学习(1)_第9张图片

预热

阈值的冷启动(clodFactory)的默认值是3,需要经过预热时长后才会到达阈值

官方说明https://github.com/alibaba/Sentinel/wiki/%E9%99%90%E6%B5%81—%E5%86%B7%E5%90%AF%E5%8A%A8

我们启动sentinel控制台

进行设置

Sentinel的初步学习(1)_第10张图片

设置完成后

默认公式是冷启动时长3s

那么预热时间就是10/3+5,也就是一开始的阈值是3,经过5s后才慢慢恢复到10

我们访问TestB请求

保持一个速率刷新,一开始会报错,宕机

后面逐渐恢复正常

也就是,一个保护机制,在开启服务时,为了保护不被流量一次性过多进入。会慢慢把流量一点点放进来,逐渐增长到阈值

排队等待

匀速排队,让请求以均匀的速度通过,阈值类型要设置成QPS,否则无效

/testA 每秒一次请求,超过的话排队等待,等待超时时间为20000毫秒

Sentinel的初步学习(1)_第11张图片

用于处理间隔性的突发流量

利用postman设置10个线程,1秒发送10个线程

出现以下情况

2020-04-29 15:45:55.853  INFO 14188 --- [nio-8401-exec-4] c.x.s.controller.SentinelController      : http-nio-8401-exec-4	=======AAAAA
2020-04-29 15:45:56.879  INFO 14188 --- [nio-8401-exec-5] c.x.s.controller.SentinelController      : http-nio-8401-exec-5	=======AAAAA
2020-04-29 15:45:57.915  INFO 14188 --- [nio-8401-exec-6] c.x.s.controller.SentinelController      : http-nio-8401-exec-6	=======AAAAA
2020-04-29 15:45:58.931  INFO 14188 --- [nio-8401-exec-7] c.x.s.controller.SentinelController      : http-nio-8401-exec-7	=======AAAAA
2020-04-29 15:45:59.952  INFO 14188 --- [nio-8401-exec-8] c.x.s.controller.SentinelController      : http-nio-8401-exec-8	=======AAAAA
2020-04-29 15:46:00.968  INFO 14188 --- [nio-8401-exec-9] c.x.s.controller.SentinelController      : http-nio-8401-exec-9	=======AAAAA
2020-04-29 15:46:01.987  INFO 14188 --- [io-8401-exec-10] c.x.s.controller.SentinelController      : http-nio-8401-exec-10	=======AAAAA
2020-04-29 15:46:03.004  INFO 14188 --- [nio-8401-exec-2] c.x.s.controller.SentinelController      : http-nio-8401-exec-2	=======AAAAA
2020-04-29 15:46:04.022  INFO 14188 --- [nio-8401-exec-1] c.x.s.controller.SentinelController      : http-nio-8401-exec-1	=======AAAAA
2020-04-29 15:46:05.043  INFO 14188 --- [nio-8401-exec-3] c.x.s.controller.SentinelController      : http-nio-8401-exec-3	=======AAAAA

这是因为队列等待设置成一秒1个

可以当作队列来理解,阀值为2,理解为同一时间读取队列中2个元素,若是一个元素处理完,读取下一个元素,剩下的元素如果在队列中等待的时间超过了timeout,就限流打回

4.熔断降级(和Hystrix最大的不同,没有半开状态)

https://github.com/alibaba/Sentinel/wiki/%E7%86%94%E6%96%AD%E9%99%8D%E7%BA%A7

和流量监控区分

流控只是对流量大小进行控制,并不会对响应超时、异常的情况进行处理

我们通常用以下几种方式来衡量资源是否处于稳定的状态:

RT (平均响应时间 )

平均响应时间 超出阈值 且 时间窗口内通过的请求 >=5 两个条件同时满足后触发降级

窗口期过后关闭断路器

RT最大 4900 (更大需要通过 -Dscp.sentinel.statistic.max.rt = XXXX 灿能生效)

异常比例 (秒级)

QPS >=5 且异常比例(秒级统计)超过阈值,触发降级,时间窗口结束后,关闭降级

异常数

异常数 (分钟统计)超过阈值,触发降级;时间窗借宿后, 关闭降级。

1.RT

平均响应时间 (DEGRADEGRADERT):当 1s 内持续进入 5 个请求,对应时刻的平均响应时间(秒级)均超过阈值(count,以 ms 为单位),那么在接下的时间窗口(DegradeRule 中的 timeWindow,以 s 为单位)之内,对这个方法的调用都会自动地熔断(抛出 DegradeException)。注意 Sentinel 默认统计的 RT 上限是 4900 ms,超出此阈值的都会算作 4900 ms,若需要变更此上限可以通过启动配置项 -Dcsp.sentinel.statistic.max.rt=xxx 来配置。

》》》》》》》》

1秒内持续5个请求,平均响应时间>阈值》》》》》》触发断路器,降级》》》》》时间窗口结束》》》》》关闭降级

测试

我们编写一个test

在sentinel控制台进行降级修改

Sentinel的初步学习(1)_第12张图片

设置完成后,启动jmeter,设置压测

Sentinel的初步学习(1)_第13张图片

启动压测,访问请求端口TestD

Sentinel的初步学习(1)_第14张图片

2.异常比例

异常比例 (DEGRADEGRADEEXCEPTION_RATIO):当资源的每秒请求量 >= 5,并且每秒异常总数占通过量的比值超过阈值(DegradeRule 中的 count)之后,资源进入降级状态,即在接下的时间窗口(DegradeRule 中的 timeWindow,以 s 为单位)之内,对这个方法的调用都会自动地返回。异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%。

》》》》》》》》》》》》

QPS>=5 && 异常比例(秒级统计)超过阈值》》》》》》触发降级,断路器打开》》》》》时间窗口期结束》》》》》关闭降级恢复正常

测试

配置sentinel

Sentinel的初步学习(1)_第15张图片

配置jmeter

Sentinel的初步学习(1)_第16张图片

Sentinel的初步学习(1)_第17张图片

启动jmeter,我们发现浏览器出现sentinel默认报错

Sentinel的初步学习(1)_第18张图片

但是一旦我们关闭jmeter,他肯定页面百分百报错

Sentinel的初步学习(1)_第19张图片

为什么会报错???

因为,我们这个时候关闭了jmeter,她请求资源数自然降下来,当请求资源数小于sentinel默认的5之后,就不会进入降级,而是直接访问我们的请求,没了降级保护,自然而然报错。

开启了jmeter,直接高并发请求,多次调用到达了我们的配置条件,断路器自然而然开启,微服务自然而然不可用。便不会报错error,而是服务降级

3.异常数

异常数 (DEGRADEGRADEEXCEPTION_COUNT):当资源近 1 分钟的异常数目超过阈值之后会进行熔断。注意由于统计时间窗口是分钟级别的,若 timeWindow 小于 60s,则结束熔断状态后仍可能再进入熔断状态。

时间窗口一定要要大于等于60秒

》》》》》》》》》

按照分钟统计,异常数超过阈值》》》》》》触发降级,断路器打开》》》》》时间窗口期结束》》》》关闭降级

测试

Sentinel的初步学习(1)_第20张图片

设置sentinel,在70秒内,如果错误数超过5次,启动服务降级

访问请求地址E

Sentinel的初步学习(1)_第21张图片

由于我们的令其百分百报错,启动sentinel的异常数配置

刷新5次之后,触发降级

Sentinel的初步学习(1)_第22张图片

当我们等待时间窗口期过去之后,断路器关闭,关闭熔断降级,进入我们的微服务,这时服务再次报错

Sentinel的初步学习(1)_第23张图片

5.热点key限流

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

商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制
用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制
热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。

Sentinel 利用 LRU 策略统计最近最常访问的热点参数,结合令牌桶算法来进行参数级别的流控。热点参数限流支持集群模式。

通俗一点也即是,如果你传入的某个值(比如p1)的请求量达到一定的量,就对p1进行限流,其他值不限

测试

我们设置了兜底的方法

我们先对sentinel控制台进行设置,设置限流第“0”位的参数

Sentinel的初步学习(1)_第24张图片

编写我们的请求代码,设置我们的兜底方法

/*
    *  测试热点限流
    *  SentinelResource这里的value值名称唯一即可,对应sentinel控制台的资源名
    *  blockHandler,BlockException 是源码里的
    *  p1,p2是我们设置的热点值(也就是sentinel里面的参数索引,对应者0,1位)
    *  自己设置兜底的方法deal_HotKey
    *  而SentinelResource基本可以看成HystrixCommand
    * */
    @GetMapping("/testHotKey")
    @SentinelResource(value = "testHotKey",blockHandler = "deal_HotKey")
    public String testHotKey(@RequestParam(value = "p1",required = false)String p1,
                             @RequestParam(value = "p2",required = false)String p2
                             ){
        return "============testHotKey";
    }

    public String deal_HotKey(String p1, String p2, BlockException exception){
        return "===========deal_HotKey======T_T";
    }

启动8401端口,进行访问

当我们缓慢访问 0 位参数-----p1时

Sentinel的初步学习(1)_第25张图片

正常通过,

但是当我们一秒内多次访问,超过阈值1的时候,出现了限流

Sentinel的初步学习(1)_第26张图片

当我们不设置兜底方法

也就是将 @SentinelResource里面的这个参数去掉 blockHandler = "deal_HotKey"

我们访问量超过阈值后

出现以下的界面

Sentinel的初步学习(1)_第27张图片

这样子异常就打到了前台,对于用户的体验极差

我们这个兜底方法也可以近似的看作我们的异常捕获try/catch

参数例外项 》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》设置当我们的限流参数达到某个值时,成为特例,不被限流(设置VIP特权)

测试

先编辑好sentinel控制台

Sentinel的初步学习(1)_第28张图片

当我们访问p1=5的时候

Sentinel的初步学习(1)_第29张图片

我们没有达到阈值,不会跳转到我们的兜底方法

也就是说,当我们的p1=5的时候阈值达到200;当你为其他数值的时候阈值只有1(也可以理解为VIP用户和普通用户的区别)

当我们的代码运行出现的异常

这种异常不属于Block Exception

这是java运行的错误

属于RunTime Exception管理

运行后直接报错

Sentinel的初步学习(1)_第30张图片

总结:@SentinelResoure只管理配置的异常,运行的出错异常不归他管理,该报错还是要报错

你可能感兴趣的:(Sentinel的初步学习(1))