• SCA Sentinel 分布式系统的流量防控(二)


    1、Sentinel 降级规则模块

      流控是对外部来的大流量进行控制,熔断降级的视角是对内部问题进行处理。

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

    这里的降级其实是Hystrix中的熔断

    Hystrix的工作流程

    策略 

            Sentinel不会像Hystrix那样放过一个请求尝试自我修复,就是明明确确按照时间窗口来,熔断触发后,时间窗口内拒绝请求,时间窗口后就恢复。

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

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

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

      时间窗口 >= 60s

     

    2、Sentinel 自定义兜底逻辑

            @SentinelResource注解类似于Hystrix中的@HystrixCommand注解,@SentinelResource注解中有两个属性需要我们进行区分,blockHandler属性用来指定不满足Sentinel规则的降级兜底方法,fallback属性用于指定Java运行时异常兜底方法 。

    (1)在API接口资源处配置

    1. package com.lagou.edu.controller;
    2. import com.alibaba.csp.sentinel.annotation.SentinelResource;
    3. import com.alibaba.csp.sentinel.slots.block.BlockException;
    4. import com.lagou.edu.config.SentinelHandlersClass;
    5. import com.lagou.edu.controller.service.ResumeServiceFeignClient;
    6. import org.springframework.beans.factory.annotation.Autowired;
    7. import org.springframework.web.bind.annotation.GetMapping;
    8. import org.springframework.web.bind.annotation.PathVariable;
    9. import org.springframework.web.bind.annotation.RequestMapping;
    10. import org.springframework.web.bind.annotation.RestController;
    11. @RestController
    12. @RequestMapping("/autodeliver")
    13. public class AutodeliverController {
    14. @Autowired
    15. private ResumeServiceFeignClient resumeServiceFeignClient;
    16. /**
    17. @SentinelResource
    18. value:定义资源名
    19. blockHandlerClass:指定Sentinel规则异常兜底逻辑所在class类
    20. blockHandler:指定Sentinel规则异常兜底逻辑具体哪个⽅法
    21. fallbackClass:指定Java运⾏时异常兜底逻辑所在class类
    22. fallback:指定Java运⾏时异常兜底逻辑具体哪个⽅法
    23. */
    24. @GetMapping("/checkState/{userId}")
    25. // @SentinelResource注解类似于Hystrix中的@HystrixCommand注解
    26. @SentinelResource(value = "findResumeOpenState",blockHandlerClass = SentinelHandlersClass.class,
    27. blockHandler = "handleException",fallbackClass = SentinelHandlersClass.class,fallback = "handleError")
    28. public Integer findResumeOpenState(@PathVariable Long userId) {
    29. // 模拟降级:
    30. /*try {
    31. Thread.sleep(1000);
    32. } catch (InterruptedException e) {
    33. e.printStackTrace();
    34. }*/
    35. // 模拟降级:异常比例
    36. //int i = 1/0;
    37. Integer defaultResumeState = resumeServiceFeignClient.findDefaultResumeState(userId);
    38. return defaultResumeState;
    39. }
    40. }

    (2)自定义兜底逻辑类(注意:兜底类中的方法为static静态方法)

    1. package com.lagou.edu.config;
    2. import com.alibaba.csp.sentinel.slots.block.BlockException;
    3. public class SentinelHandlersClass {
    4. // 整体要求和当时Hystrix一样,这里还需要在形参中添加BlockException参数,用于接收异常
    5. // 注意:方法是静态的
    6. public static Integer handleException(Long userId, BlockException blockException) {
    7. return -100;
    8. }
    9. public static Integer handleError(Long userId) {
    10. return -500;
    11. }
    12. }

    3、基于 Nacos 实现 Sentinel 规则持久化

            目前,Sentinel Dashboard中添加的规则数据存储在内存,微服务停掉规则数据就消失,在生产环境下不合适。我们可以将Sentinel规则数据持久化到Nacos配置中心,让微服务从Nacos获取规则数据。

    (1) 自动投递微服务的pom.xml中添加依赖

    1. <dependency>
    2. <groupId>com.alibaba.cspgroupId>
    3. <artifactId>sentinel-datasource-nacosartifactId>
    4. dependency>

    (2)自动投递微服务的application.yml中配置Nacos数据源

    1. server:
    2. port: 8098
    3. spring:
    4. application:
    5. name: lagou-service-autodeliver
    6. cloud:
    7. nacos:
    8. discovery:
    9. server-addr: 127.0.0.1:8848,127.0.0.1:8849,127.0.0.1:8850
    10. sentinel:
    11. transport:
    12. dashboard: 127.0.0.1:8080 # sentinel dashboard/console 地址
    13. port: 8719 # sentinel会在该端口启动http server,那么这样的话,控制台定义的一些限流等规则才能发送传递过来,
    14. #如果8719端口被占用,那么会依次+1
    15. # Sentinel Nacos数据源配置,Nacos中的规则会自动同步到sentinel流控规则中
    16. datasource:
    17. # 自定义的流控规则数据源名称
    18. flow: # 此处的flow为自定义数据源名
    19. nacos:
    20. server-addr: ${spring.cloud.nacos.discovery.server-addr}
    21. data-id: ${spring.application.name}-flow-rules
    22. groupId: DEFAULT_GROUP
    23. data-type: json
    24. rule-type: flow # 类型来自RuleType类
    25. # 自定义的降级规则数据源名称
    26. degrade:
    27. nacos:
    28. server-addr: ${spring.cloud.nacos.discovery.server-addr}
    29. data-id: ${spring.application.name}-degrade-rules
    30. groupId: DEFAULT_GROUP
    31. data-type: json
    32. rule-type: degrade # 类型来自RuleType类

    (3)Nacos Server中添加对应规则配置集(public命名空间—>DEFAULT_GROUP中添加)

            流控规则配置集 lagou-service-autodeliver-flow-rules

    1. [
    2. {
    3. "resource":"findResumeOpenState",
    4. "limitApp":"default",
    5. "grade":1,
    6. "count":1,
    7. "strategy":0,
    8. "controlBehavior":0,
    9. "clusterMode":false
    10. }
    11. ]

      所有属性来自源码FlowRule类

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

            降级规则配置集 lagou-service-autodeliver-degrade-rules

    1. [
    2. {
    3. "resource":"findResumeOpenState",
    4. "grade":2,
    5. "count":1,
    6. "timeWindow":5
    7. }
    8. ]

      所有属性来自源码DegradeRule类

    • resource:资源名称
    • grade:降级策略 0 RT 1 异常⽐例 2 异常数
    • count:阈值
    • timeWindow:时间窗

    Rule 源码体系结构

    注意 

    1. 一个资源可以同时有多个限流规则和降级规则,所以配置集中是一个json数组
    2. Sentinel控制台中修改规则,仅是内存中生效,不会修改Nacos中的配置值,重启后恢复原来的值; Nacos控制台中修改规则,不仅内存中生效,Nacos中持久化规则也生效,重启后规则依然保持 。
  • 相关阅读:
    蜂鸣器电路设计中选用注意事项--【电路设计】
    根据两向量求旋转矩阵(C++)
    http协议各个版本的详细介绍
    手把手教你Nginx常用模块详解之ngx_http_api_module(三)
    解决flume采集日志使用KafkaChannel写不到hdfs的问题
    Allegro如何输出EMN文件操作指导
    【ElasticSearch笔记】
    【Qt】QPalette
    ArrayList源码解析
    容器环境 springcloud gateway grafana prometheus采集集成与问题
  • 原文地址:https://blog.csdn.net/weixin_52851967/article/details/126676300