• Spring Cloud Alibaba Sentinel


    https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinel

    Sentinel 介绍

    随着微服务的流行,服务和服务之间的稳定性变得越来越重要。 Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

    Sentinel 具有以下特征:

    • 丰富的应用场景: Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、实时熔断下游不可用应用等。

    • 完备的实时监控: Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。

    • 广泛的开源生态: Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。

    • 完善的 SPI 扩展点: Sentinel 提供简单易用、完善的 SPI 扩展点。您可以通过实现扩展点,快速的定制逻辑。例如定制规则管理、适配数据源等。

    https://github.com/alibaba/Sentinel/wiki/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8

    pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <!--    <parent>-->
    <!--        <artifactId>springcloudalibaba</artifactId>-->
    <!--        <groupId>com.wsm.springcloud</groupId>-->
    <!--        <version>0.0.1-SNAPSHOT</version>-->
    <!--    </parent>-->
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.5.6</version>
            <relativePath></relativePath>
        </parent>
    
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>sentinel_demo</artifactId>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <!--            <version>2.5.5</version>-->
            </dependency>
    
            <!-- sentinel 核心库 -->
            <!-- https://mvnrepository.com/artifact/com.alibaba.csp/sentinel-core -->
            <dependency>
                <groupId>com.alibaba.csp</groupId>
                <artifactId>sentinel-core</artifactId>
                <version>1.8.2</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.22</version>
                <scope>provided</scope>
            </dependency>
    
            <!-- 如果要使用@SentinelResource -->
            <!-- https://mvnrepository.com/artifact/com.alibaba.csp/sentinel-annotation-aspectj -->
            <dependency>
                <groupId>com.alibaba.csp</groupId>
                <artifactId>sentinel-annotation-aspectj</artifactId>
                <version>1.8.2</version>
            </dependency>
    
    
        </dependencies>
    
    </project>

    application.yml

    server:
      port: 8051

    Sentinel 支持以下几种规则:流量控制规则、熔断降级规则、系统保护规则、来源访问控制规则 和 热点参数规则。

    流量控制规则 (FlowRule)

    流量规则的定义

    重要属性:

    Field说明默认值
    resource 资源名,资源名是限流规则的作用对象  
    count 限流阈值  
    grade 限流阈值类型,QPS 模式(1)或并发线程数模式(0) QPS 模式
    limitApp 流控针对的调用来源 default,代表不区分调用来源
    strategy 调用关系限流策略:直接、链路、关联 根据资源本身(直接)
    controlBehavior 流控效果(直接拒绝/WarmUp/匀速+排队等待),不支持按调用关系限流 直接拒绝
    clusterMode 是否集群限流

    同一个资源可以同时有多个限流规则,检查规则时会依次检查。

    理解上面规则的定义之后,我们可以通过调用 FlowRuleManager.loadRules() 方法来用硬编码的方式定义流量控制规则

    //进行sentinel限流
        @RequestMapping(value = "/hello")
        public String hello() {
            Entry entry = null;
            try {
                //sentinel 针对资源进行限制
                entry = SphU.entry(RESOURCE_NAME);
                //被保护的业务逻辑
                String str = "hello world";
                log.info("======="+str+"========");
                return str;
            }catch (BlockException el){
                //资源访问阻止,被限流或被降级
                //进行相应的处理操作
                log.info("block!");
                return "被流控了!";
            }catch (Exception ex){
                //若需要配置降级,需要通过这种方式记录业务异常
                Tracer.traceEntry(ex,entry);
            }finally {
                if(entry != null){
                    entry.exit();
                }
            }
            return null;
        }
    
        /**
         * 定义规则
         *
         * spring 的初始化方法
         */
        @PostConstruct // init-method  Spring注解  Bean创建的时候会调用这个方法进行初始化
        private static void initFlowRules(){
    
            //流控规则
            List<FlowRule> rules = new ArrayList<>();
            //流控
            FlowRule rule = new FlowRule();
            //设置受保护的资源
            rule.setResource(RESOURCE_NAME);
            //设置流控规则 QPS
            rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
            //设置受保护的资源阈值  QPS每秒访问数
            rule.setCount(1);
            rules.add(rule);
    
            //流控
            FlowRule rule2 = new FlowRule();
            //设置受保护的资源
            rule2.setResource(USER_RESOURCE_NAME);
            //设置流控规则 QPS
            rule2.setGrade(RuleConstant.FLOW_GRADE_QPS);
            //设置受保护的资源阈值  QPS每秒访问数
            rule2.setCount(1);
            rules.add(rule2);
            FlowRuleManager.loadRules(rules);
        }
    package com.wsm.sentinel.controller;
    
    import com.alibaba.csp.sentinel.Entry;
    import com.alibaba.csp.sentinel.SphU;
    import com.alibaba.csp.sentinel.Tracer;
    import com.alibaba.csp.sentinel.slots.block.BlockException;
    import com.alibaba.csp.sentinel.slots.block.RuleConstant;
    import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
    import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
    import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
    import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
    import com.alibaba.csp.sentinel.slots.system.SystemRule;
    import com.alibaba.csp.sentinel.slots.system.SystemRuleManager;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.annotation.PostConstruct;
    import java.util.ArrayList;
    import java.util.List;
    
    @RestController
    @Slf4j
    public class HelloController {
    
        private static final String RESOURCE_NAME="hello";
        private static final String USER_RESOURCE_NAME = "user";
        private static final String DEGRADE_RESOURCE_NAME = "degrade";
    
        //进行sentinel限流
        @RequestMapping(value = "/hello")
        public String hello() {
            Entry entry = null;
            try {
                //sentinel 针对资源进行限制
                entry = SphU.entry(RESOURCE_NAME);
                //被保护的业务逻辑
                String str = "hello world";
                log.info("======="+str+"========");
                return str;
            }catch (BlockException el){
                //资源访问阻止,被限流或被降级
                //进行相应的处理操作
                log.info("block!");
                return "被流控了!";
            }catch (Exception ex){
                //若需要配置降级,需要通过这种方式记录业务异常
                Tracer.traceEntry(ex,entry);
            }finally {
                if(entry != null){
                    entry.exit();
                }
            }
            return null;
        }
    
        /**
         * 定义规则
         *
         * spring 的初始化方法
         */
        @PostConstruct // init-method  Spring注解  Bean创建的时候会调用这个方法进行初始化
        private static void initFlowRules(){
    
            //流控规则
            List<FlowRule> rules = new ArrayList<>();
            //流控
            FlowRule rule = new FlowRule();
            //设置受保护的资源
            rule.setResource(RESOURCE_NAME);
            //设置流控规则 QPS
            rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
            //设置受保护的资源阈值  QPS每秒访问数
            rule.setCount(1);
            rules.add(rule);
            FlowRuleManager.loadRules(rules);
        }
    
    
        // 限流规则
        private void initFlowQpsRule() {
            List<FlowRule> rules = new ArrayList<>();
            FlowRule rule = new FlowRule(RESOURCE_NAME);
            // set limit qps to 20
            rule.setCount(20);
            rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
            rule.setLimitApp("default");
            rules.add(rule);
            FlowRuleManager.loadRules(rules);
        }
    
        private void initDegradeRule() {
            List<DegradeRule> rules = new ArrayList<>();
            DegradeRule rule = new DegradeRule();
            rule.setResource(DEGRADE_RESOURCE_NAME);
            // set threshold RT, 10 ms
            rule.setCount(10);
            rule.setGrade(RuleConstant.DEGRADE_GRADE_RT);
            rule.setTimeWindow(10);
            rules.add(rule);
            DegradeRuleManager.loadRules(rules);
        }
    
        private void initSystemRule() {
            List<SystemRule> rules = new ArrayList<>();
            SystemRule rule = new SystemRule();
            rule.setHighestSystemLoad(10);
            rules.add(rule);
            SystemRuleManager.loadRules(rules);
        }
    
        @GetMapping("/rule_setting")
        //代码配置sentinel限流规则
        public String initFlowRule(){
            //规则集合
            List<FlowRule> rules = new ArrayList<>();
            //创建新的规则对象,"/list"就是资源名
            FlowRule rule = new FlowRule("/list");
            //直接策略
            rule.setStrategy(RuleConstant.STRATEGY_DIRECT);
            //采用QPS限速模式
            rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
            //限制QPS为100
            rule.setCount(100);
            //流控效果设置为“预热”
            rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_WARM_UP);
            //预热时间20秒
            rule.setWarmUpPeriodSec(20);
            //来源设置为默认所有default
            rule.setLimitApp("default");
            rules.add(rule);
            //设置,FlowRuleManager是Sentinel规则管理器
            FlowRuleManager.loadRules(rules);
            return "SUCCESS";
    
    
        }
    
    }

    熔断降级规则 (DegradeRule)

    熔断降级规则包含下面几个重要的属性:

    Field说明默认值
    resource 资源名,即规则的作用对象  
    grade 熔断策略,支持慢调用比例/异常比例/异常数策略 慢调用比例
    count 慢调用比例模式下为慢调用临界 RT(超出该值计为慢调用);异常比例/异常数模式下为对应的阈值  
    timeWindow 熔断时长,单位为 s  
    minRequestAmount 熔断触发的最小请求数,请求数小于该值时即使异常比率超出阈值也不会熔断(1.7.0 引入) 5
    statIntervalMs 统计时长(单位为 ms),如 60*1000 代表分钟级(1.8.0 引入) 1000 ms
    slowRatioThreshold 慢调用比例阈值,仅慢调用比例模式有效(1.8.0 引入)  

    同一个资源可以同时有多个降级规则。

    Sentinel 的三种失败指标
    • 一秒内(请求数大于等于 5)响应时间超过某个值:RuleConstant.DEGRADE_GRADE_RT;
    • 一秒内(请求数大于等于 5)的错误比率:RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO;
    • 一分钟内的错误数量:RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT;

    理解上面规则的定义之后,我们可以通过调用 DegradeRuleManager.loadRules() 方法来用硬编码的方式定义流量控制规则。

    @PostConstruct
        public void initDegradeRules(){
    //        一秒内(请求数大于等于 5)响应时间超过某个值:RuleConstant.DEGRADE_GRADE_RT;
    //        一秒内(请求数大于等于 5)的错误比率:RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO;
    //        一分钟内的错误数量:RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT;
    
            List<DegradeRule> rules = new ArrayList<>();
            DegradeRule rule = new DegradeRule();
            rule.setResource(DEGRADE_RESOURCE_NAME);
            //异常比例/异常数模式下为对应的阈值
            rule.setCount(0.1);
            //熔断策略,异常比例/异常数策略
            rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO);
            // 熔断时长,单位为 s
            rule.setTimeWindow(10);
    //        rule.setMinRequestAmount(2);
    //        rule.setStatIntervalMs(60*1000*60);//时间太短不好测
            rules.add(rule);
    
            DegradeRule rule2 = new DegradeRule();
            rule2.setResource(DEGRADE_RESOURCE_NAME);
            //慢调用比例模式下为慢调用临界 RT(超出该值计为慢调用);
            // set threshold RT, 10 ms
            rule2.setCount(10);
            //熔断策略,支持慢调用比例 -- DEGRADE_GRADE_RT
            rule2.setGrade(RuleConstant.DEGRADE_GRADE_RT);
            // 熔断时长,单位为 s
            rule2.setTimeWindow(10);
    //        请求总数小于minRequestAmount(2);
            rule2.setMinRequestAmount(2);
    //        在这个时间段内2次请求
            rule2.setStatIntervalMs(60*1000*60);//时间太短不好测
    //        慢请求率: 慢请求数/总请求数> SlowRatioThreshold , 这里要设置小于1 因为慢请求数/总请求数就远不会大于1
            rule2.setSlowRatioThreshold(0.9);
            rules.add(rule2);
            DegradeRuleManager.loadRules(rules);
    
        }
     

    系统保护规则 (SystemRule)

    Sentinel 系统自适应限流从整体维度对应用入口流量进行控制,结合应用的 Load、CPU 使用率、总体平均 RT、入口 QPS 和并发线程数等几个维度的监控指标,通过自适应的流控策略,让系统的入口流量和系统的负载达到一个平衡,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。

    系统规则包含下面几个重要的属性:

    Field说明默认值
    highestSystemLoad load1 触发值,用于触发自适应控制阶段 -1 (不生效)
    avgRt 所有入口流量的平均响应时间 -1 (不生效)
    maxThread 入口流量的最大并发数 -1 (不生效)
    qps 所有入口资源的 QPS -1 (不生效)
    highestCpuUsage 当前系统的 CPU 使用率(0.0-1.0) -1 (不生效)

    理解上面规则的定义之后,我们可以通过调用 SystemRuleManager.loadRules() 方法来用硬编码的方式定义流量控制规则。

    访问控制规则 (AuthorityRule)

    很多时候,我们需要根据调用方来限制资源是否通过,这时候可以使用 Sentinel 的访问控制(黑白名单)的功能。黑白名单根据资源的请求来源(origin)限制资源是否通过,若配置白名单则只有请求来源位于白名单内时才可通过;若配置黑名单则请求来源位于黑名单时不通过,其余的请求通过。

    授权规则,即黑白名单规则(AuthorityRule)非常简单,主要有以下配置项:

    • resource:资源名,即规则的作用对象
    • limitApp:对应的黑名单/白名单,不同 origin 用 , 分隔,如 appA,appB
    • strategy:限制模式,AUTHORITY_WHITE 为白名单模式,AUTHORITY_BLACK 为黑名单模式,默认为白名单模式

  • 相关阅读:
    最大堆的实现
    更新Android SDK Manager Mac下修改hosts
    快速排序
    含有通配符的字符串匹配(递归)
    geopandas安装问题记录:ImportError,DLL load failedwindows10
    silveright 5.0 搜索代码生成系统
    Insert xml to DB Column
    Enter/Esc Hot Key Silverlight
    Silverlight 页面保存为html出现乱码的问题
    Use dynamic SQL to fix openrowset parameter and Insert xml files into database under given folder
  • 原文地址:https://www.cnblogs.com/mingforyou/p/15582133.html
Copyright © 2020-2023  润新知