0


Sentinel

1、运行

命令:

java -jar sentinel-dashboard-1.7.0.jar

yml:

server:
  port:8401

spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #Nacos服务注册中心地址
    sentinel:
      transport:
        dashboard: localhost:8080 #配置Sentinel dashboard地址
        port:8719
      datasource:
        ds1:
          nacos:
            server-addr: localhost:8848
            dataId: cloudalibaba-sentinel-service
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow

management:
  endpoints:
    web:
      exposure:
        include:'*'

feign:
  sentinel:
    enabled:true # 激活Sentinel对Feign的支持

访问前台界面:

http://localhost:8080

,Sentinel使用的是懒加载,只有当真正访问业务的时候才会监控。
在这里插入图片描述

2、Sentinel流量控制(流控)

1、QPS直接失败

在这里插入图片描述
QPS是一秒内访问数,超过设置的阈值将会报错
在这里插入图片描述
思考
直接调用默认报错信息,技术方面OK,但是,是否应该有我们自己的后续处理?类似有个fallback的兜底方法?

2、线程数直接失败

线程数:当调用该API的线程数达到阈值的时候,进行限流。
在这里插入图片描述

3、关联

是什么?

  • 当自己关联的资源达到阈值时,就限流自己
  • 当与A关联的资源B达到阀值后,就限流A自己(B惹事,A挂了)

设置testA

当关联资源/testB的QPS阀值超过1时,就限流/testA的Rest访问地址,当关联资源到阈值后限制配置好的资源名。

在这里插入图片描述
用postman发送,启用20个进程,每隔0.3秒访问一次,
在这里插入图片描述
在这里插入图片描述

4、预热

默认coldFactor为3,即请求QPS 从 threshold / 3开始,经预热时长逐渐升至设定的QPS阈值
在这里插入图片描述
WarmUp配置

案例,阀值为10,预热时长设置5秒。

系统初始化的阀值为10/ 3约等于3,即阀值刚开始为3;然后过了5秒后阀值才慢慢升高恢复到10

在这里插入图片描述
测试

多次快速点击http://localhost:8401/testB - 刚开始不行,后续慢慢OK

应用场景

如:秒杀系统在开启的瞬间,会有很多流量上来,很有可能把系统打死,预热方式就是把为了保护系统,可慢慢的把流量放进来,慢慢的把阀值增长到设置的阀值。

5、排队等待

匀速排队,让请求以均匀的速度通过,阀值类型必须设成QPS,否则无效。

设置:/testA每秒1次请求,超过的话就排队等待,等待的超时时间为20000毫秒。

在这里插入图片描述

6、Sentinel降级

在这里插入图片描述

  • RT(平均响应时间,秒级)- 平均响应时间 超出阈值 且 在时间窗口内通过的请求>=5,两个条件同时满足后触发降级。- 窗口期过后关闭断路器。- RT最大4900(更大的需要通过-Dcsp.sentinel.statistic.max.rt=XXXX才能生效)。
  • 异常比列(秒级)- QPS >= 5且异常比例(秒级统计)超过阈值时,触发降级;时间窗口结束后,关闭降级 。
  • 异常数(分钟级)- 异常数(分钟统计)超过阈值时,触发降级;时间窗口结束后,关闭降级

Sentinel熔断降级会在调用链路中某个资源出现不稳定状态时(例如调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联错误。

当资源被降级后,在接下来的降级时间窗口之内,对该资源的调用都自动熔断(默认行为是抛出 DegradeException)。

Sentinei的断路器是没有类似Hystrix半开状态的。(Sentinei 1.8.0 已有半开状态)

半开的状态系统自动去检测是否请求有异常,没有异常就关闭断路器恢复使用,有异常则继续打开断路器不可用。

1、Sentinel降级-RT

设置RT为0.2秒,时间窗口是1秒
在这里插入图片描述
在这里插入图片描述
在jmeter设置一秒发10个线程,这样必然会导致系统崩溃
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、异常比例

是什么?

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

注意,与Sentinel 1.8.0相比,有些不同(Sentinel 1.8.0才有的半开状态),Sentinel 1.8.0的如下:

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

设置异常超过百分之20,3秒内不可用
在这里插入图片描述
按照上述配置,单独访问一次,必然来一次报错一次(int age = 10/0),调一次错一次。

开启jmeter后,直接高并发发送请求,多次调用达到我们的配置条件了。断路器开启(保险丝跳闸),微服务不可用了,不再报错error而是服务降级了。

3、异常数

是什么?
异常数( DEGRADE_GRADF_EXCEPTION_COUNT ):当资源近1分钟的异常数目超过阈值之后会进行熔断。注意由于统计时间窗口是分钟级别的,若timeWindow小于60s,则结束熔断状态后码可能再进入熔断状态。
在这里插入图片描述
当发生异常数后,要在时间窗口后规定的时间后才能正常访问。

7、Sentinel热点key(上)

兜底方法,分为系统默认和客户自定义,两种

之前的case,限流出问题后,都是用sentinel系统默认的提示: Blocked by Sentinel (flow limiting)

我们能不能自定?类似hystrix,某个方法出问题了,就找对应的兜底降级方法?

结论 - 从HystrixCommand到@SentinelResource

@RestController@Slf4jpublicclassFlowLimitController{...@GetMapping("/testHotKey")@SentinelResource(value ="testHotKey",blockHandler/*兜底方法*/="deal_testHotKey")publicStringtestHotKey(@RequestParam(value ="p1",required =false)String p1,@RequestParam(value ="p2",required =false)String p2){//int age = 10/0;return"------testHotKey";}/*兜底方法*/publicString deal_testHotKey (String p1,String p2,BlockException exception){return"------deal_testHotKey,o(╥﹏╥)o";//sentinel系统默认的提示:Blocked by Sentinel (flow limiting)}}

配置
在这里插入图片描述

在这里插入图片描述

8、Sentinel热点key(下)(参数例外项)

在这里插入图片描述
配置
在这里插入图片描述
总结
在这里插入图片描述

8、Sentinel系统规则

简单的说就是系统级别的规则,单系统访问量达到一定级别时候,整个系统就访问不了了
在这里插入图片描述
在这里插入图片描述
参数解读:
在这里插入图片描述

9、SentinelResource配置(上)

Sentinel相当于HystrixCommand

@GetMapping("/byResource")@SentinelResource(value ="byResource",blockHandler ="handleException")publicCommonResultbyResource(){returnnewCommonResult(200,"按资源名称限流测试OK",newPayment(2020L,"serial001"));}publicCommonResulthandleException(BlockException exception){returnnewCommonResult(444,exception.getClass().getCanonicalName()+"\t 服务不可用");}

设置流控,当一秒内访问数大于1时,就会走到我们自定义的方法里面
在这里插入图片描述
在这里插入图片描述
此时如果关闭8804服务,流控规则会消失吗?
在这里插入图片描述
可以看出,当关闭服务后,流控规则也消失了,那么怎样才能让流控规则持久化呢?

上面兜底方案面临的问题

  1. 系统默认的,没有体现我们自己的业务要求。
  2. 依照现有条件,我们自定义的处理方法又和业务代码耦合在一块,不直观。
  3. 每个业务方法都添加—个兜底的,那代码膨胀加剧。
  4. 全局统—的处理方法没有体现。

10、SentinelResource配置(下)

解决思路是自己创建一个类,这个类里面有很多处理的方法,然后SentinelResource调用。
在这里插入图片描述

publicclassCustomerBlockHandler{publicstaticCommonResulthandlerException(BlockException exception){returnnewCommonResult(4444,"按客戶自定义,global handlerException----1");}publicstaticCommonResulthandlerException2(BlockException exception){returnnewCommonResult(4444,"按客戶自定义,global handlerException----2");}}

业务代码:

@GetMapping("/rateLimit/customerBlockHandler")@SentinelResource(value ="customerBlockHandler",
            blockHandlerClass =CustomerBlockHandler.class,
            blockHandler ="handlerException2")publicCommonResultcustomerBlockHandler(){returnnewCommonResult(200,"按客戶自定义",newPayment(2020L,"serial003"));}}

结果截图:
在这里插入图片描述

11、Sentinel服务熔断

在这里插入图片描述
在这里插入图片描述

12、fallback

@RequestMapping("/consumer/fallback/{id}")@SentinelResource(value ="fallback",fallback ="handlerFallback")//fallback只负责业务异常publicCommonResult<Payment>fallback(@PathVariableLong id){CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL +"/paymentSQL/"+id,CommonResult.class,id);if(id ==4){thrownewIllegalArgumentException("IllegalArgumentException,非法参数异常....");}elseif(result.getData()==null){thrownewNullPointerException("NullPointerException,该ID没有对应记录,空指针异常");}return result;}//本例是fallbackpublicCommonResulthandlerFallback(@PathVariableLong id,Throwable e){Payment payment =newPayment(id,"null");returnnewCommonResult<>(444,"兜底异常handlerFallback,exception内容  "+e.getMessage(),payment);}

在这里插入图片描述

13、blockhander

blocker不管java运行时异常,只管并发访问异常。

publicCommonResultblockHandler(@PathVariableLong id,BlockException blockException){Payment payment =newPayment(id,"null");returnnewCommonResult<>(445,"blockHandler-sentinel限流,无此流水: blockException  "+blockException.getMessage(),payment);}

这将代替sentinel默认的异常输出

14、fallback和blockhander

在这里插入图片描述

15、exceptionsToIgnore

@SentinelResource(value ="fallback",fallback ="handlerFallback",blockHandler ="blockHandler",
            exceptionsToIgnore ={IllegalArgumentException.class})publicCommonResult<Payment>fallback(@PathVariableLong id){CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL +"/paymentSQL/"+id,CommonResult.class,id);if(id ==4){thrownewIllegalArgumentException("IllegalArgumentException,非法参数异常....");}elseif(result.getData()==null){thrownewNullPointerException("NullPointerException,该ID没有对应记录,空指针异常");}return result;}

忽略指定的异常,也就是输入4异常处理忽略。
在这里插入图片描述

在这里插入图片描述

16、Sentinel服务熔断OpenFeign

  • 84消费者调用提供者9003
  • Feign组件一般是消费侧

POM

<!--SpringCloud openfeign --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>

YML

<!--SpringCloud openfeign --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>

业务类

带@Feignclient注解的业务接口,fallback = PaymentFallbackService.class

importcom.atguigu.springcloud.entities.CommonResult;importcom.atguigu.springcloud.entities.Payment;importorg.springframework.cloud.openfeign.FeignClient;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.PathVariable;@FeignClient(value ="nacos-payment-provider",fallback =PaymentFallbackService.class)publicinterfacePaymentService{@GetMapping(value ="/paymentSQL/{id}")publicCommonResult<Payment>paymentSQL(@PathVariable("id")Long id);}
importcom.atguigu.springcloud.entities.CommonResult;importcom.atguigu.springcloud.entities.Payment;importorg.springframework.stereotype.Component;@ComponentpublicclassPaymentFallbackServiceimplementsPaymentService{@OverridepublicCommonResult<Payment>paymentSQL(Long id){returnnewCommonResult<>(44444,"服务降级返回,---PaymentFallbackService",newPayment(id,"errorSerial"));}}

Controller

@RestController@Slf4jpublicclassCircleBreakerController{...//==================OpenFeign@ResourceprivatePaymentService paymentService;@GetMapping(value ="/consumer/paymentSQL/{id}")publicCommonResult<Payment>paymentSQL(@PathVariable("id")Long id){return paymentService.paymentSQL(id);}}

测试 - http://localhost:84/consumer/paymentSQL/1

测试84调用9003,此时故意关闭9003微服务提供者,84消费侧自动降级,不会被耗死。
在这里插入图片描述
熔断框架比较
在这里插入图片描述

17、Sentinel持久化规则

是什么

一旦我们重启应用,sentinel规则将消失,生产环境需要将配置规则进行持久化。

怎么玩

将限流配置规则持久化进Nacos保存,只要刷新8401某个rest地址,sentinel控制台的流控规则就能看到,只要Nacos里面的配置不删除,针对8401上sentinel上的流控规则持续有效。

步骤

修改cloudalibaba-sentinel-service8401

POM

<!--SpringCloud ailibaba sentinel-datasource-nacos 后续做持久化用到--><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId></dependency>

YML

server:
  port:8401

spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #Nacos服务注册中心地址
    sentinel:
      transport:
        dashboard: localhost:8080 #配置Sentinel dashboard地址
        port:8719
      datasource: #<---------------------------关注点,添加Nacos数据源配置
        ds1:
          nacos:
            server-addr: localhost:8848
            dataId: cloudalibaba-sentinel-service
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow

management:
  endpoints:
    web:
      exposure:
        include:'*'

feign:
  sentinel:
    enabled:true # 激活Sentinel对Feign的支持

添加Nacos业务规则配置
在这里插入图片描述
配置内容解析

[{"resource":"/rateLimit/byUrl","limitApp":"default","grade":1,"count":1,"strategy":0,"controlBehavior":0,"clusterMode":false}]

resource:资源名称;
limitApp:来源应用;
grade:阈值类型,0表示线程数, 1表示QPS;
count:单机阈值;
strategy:流控模式,0表示直接,1表示关联,2表示链路;
controlBehavior:流控效果,0表示快速失败,1表示Warm Up,2表示排队等待;

启动8401后刷新sentinel发现业务规则有了
在这里插入图片描述

标签: sentinel postman java

本文转载自: https://blog.csdn.net/qq_57818853/article/details/130584854
版权归原作者 杭州下小雨~ 所有, 如有侵权,请联系我们删除。

“Sentinel”的评论:

还没有评论