Sentinel流控和降级方案

Sentinel介绍

  • 阿里巴巴中间件,负责流量控制和熔断降级。
  • 适配Spring类框架
  • 可原生开发

引入pom

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<sentinel.version>1.7.1</sentinel.version>

<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>${sentinel.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-annotation-aspectj</artifactId>
<version>${sentinel.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
<version>${sentinel.version}</version>
</dependency>
  • sentinel-core核心包
  • sentinel-annotation-aspectj适合spring切面和注解
  • sentinel-transport-simple-http便于接入console控制台

    SpringBoot配置

    1
    2
    3
    4
    5
    6
    7
    @Configuration
    public class SentinelAspectConfiguration {
    @Bean
    public SentinelResourceAspect sentinelResourceAspect() {
    return new SentinelResourceAspect();
    }
    }
  • 负责切面拦截

    1
    2
    3
    4
    @SentinelResource(value = "action")
    public boolean action(String str){
    return "Hi";
    }
  • SentinelResource为Sentinel的注解

  • value为资源标识

流控配置

1
2
3
4
5
6
7
@Data
@ToString
public static class Flow {
private String resource;
private int count;
private int grade;
}
  • Flow为自定义的配置文件
  • resource为资源名称
  • count为流控的阈值,线程数或QPS
  • grade流控类型,0-线程,1-QPS

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    /**
    * 刷新Flow
    */
    public synchronized void reloadFlow() {
    List<FlowRule> rules = new ArrayList<>(20);

    flows.forEach(e -> {
    if (StringUtils.isEmpty(e.getResource()) || e.getCount() == 0) {
    return;
    }
    log.warn(e.toString());

    FlowRule rule = new FlowRule();
    rule.setResource(e.getResource());
    //qps
    rule.setCount(e.getCount());
    rule.setGrade(e.getGrade());
    rules.add(rule);
    });

    if (rules.size() > 0) {
    FlowRuleManager.loadRules(rules);
    log.warn("Sentinel reloadFlow success!");
    }
    }
  • 导入自定义的流控配置

    降级配置

    1
    2
    3
    4
    5
    6
    7
    8
    @Data
    @ToString
    public static class Degrade {
    private String resource;
    private int count;
    private int grade;
    private int window;
    }
  • Degrade为自定义的降级配置文件

  • resource为资源名称
  • window为降级后持续的窗口时长,平均响应时间-秒、异常百分比-秒或异常数量-秒
  • count为降级的参考指标,qps=5时的平均响应时间(最大为4.9s)、qps>=5时异常百分比或默认1分钟的异常数量
  • grade降级类型,平均响应时间-0、异常百分比-1或异常数量-2

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    /**
    * 刷新Degrade
    */
    public synchronized void reloadDegrade() {
    List<DegradeRule> rules = new ArrayList<>(20);

    degrades.forEach(e -> {
    if (StringUtils.isEmpty(e.getResource()) || e.getCount() == 0 || e.getWindow() == 0) {
    return;
    }
    log.warn(e.toString());
    DegradeRule rule = new DegradeRule();
    rule.setResource(e.getResource());
    //rt,ms
    rule.setCount(e.getCount());
    rule.setGrade(e.getGrade());
    //secs
    rule.setTimeWindow(e.getWindow());
    rules.add(rule);
    });

    if (rules.size() > 0) {
    DegradeRuleManager.loadRules(rules);
    log.warn("Sentinel reloadDegrade success!");
    }
    }
  • 导入自定义的流控配置

  • 慎重配置降级策略,若降级,影响范围是window时间内的请求都处于自动降级中

Fallback和BlockHandler

  • Fallback,当异常时的处理策略,即有异常的容错方案;Fallback参数要和业务方法保持一致
  • BlockHandler,被流控或降级时,指定窗口内的降级方案;BlockHandler参数要和业务方法保持一致,同时新增一个BlockException参数

Case

  • 降级策略

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    sentinel:
    flows[0]: #流控
    resource: action
    count: 1000 #number
    grade: 1 #thread-0,qps-1
    degrades[0]: # 降级
    resource: action
    window: 120 #rt-s,exceptionRatio-s,exceptionCount-s
    count: 100 #rt-art,exceptionRatio-[0.0,1.0],exceptionCount-number
    grade: 2 #RuleConstant:rt-0,exceptionRatio-1,exceptionCount/m-2
  • 业务注解

    1
    2
    3
    4
    @SentinelResource(value = "action",fallback = "defaultFallback", blockHandler = "defaultBlockHandler")
    public boolean action(String str){
    return "Hi";
    }
1
2
3
4
5
6
public boolean defaultBlockHandler(String str, BlockException ex){
return "Hi1";
}
public boolean defaultFallback(String str){
return "Hi2";
}

控制台

  • 下载源码启动即可
  • 控制台可浏览和配置资源策略,基于内存
  • 建议对接DB或Nacos
  • 集群限流略微复杂,需要注意业务适配度及集群本身对应用的影响
------ 本文结束------

本文标题:Sentinel流控和降级方案

文章作者:Perkins

发布时间:2020年04月14日

原始链接:https://perkins4j2.github.io/posts/28431/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。