技术交流28群

服务热线

135-6963-3175

微信服务号

sentinel限流 更新时间 2019-6-10 浏览2259次

Sentinel限流

1、定义资源

2、定义规则

3、检验规则是否生效


定义资源

1、主流框架默认适配

2、抛出异常方式定义资源

// 资源名可使用任意有业务语义的字符串,比如方法名、接口名或其它可唯一标识的字符串。
try (Entry entry = SphU.entry("resourceName")) {
  // 被保护的业务逻辑
  // do something here...
} catch (BlockException ex) {
  // 资源访问阻止,被限流或被降级
  // 在此处进行相应的处理操作
}

3、返回布尔值方式定义资源

// 资源名可使用任意有业务语义的字符串
  if (SphO.entry("自定义资源名")) {
    // 务必保证finally会被执行
    try {
      /**
      * 被保护的业务逻辑
      */
    } finally {
      SphO.exit();
    }
  } else {
    // 资源访问阻止,被限流或被降级
    // 进行相应的处理操作
  }

注意:SphO.entry(xxx) 需要与 SphO.exit()方法成对出现,匹配调用,位置正确,否则会导致调用链记录异常,抛出ErrorEntryFreeException` 异常。

4、注解方式定义资源

通过@SentinelResource 注解定义资源并配置 blockHandler 和 fallback 函数来进行限流之后的处理

// 原本的业务方法.
@SentinelResource(blockHandler = "blockHandlerForGetUser")
public User getUserById(String id) {
    throw new RuntimeException("getUserById command failed");
}
// blockHandler 函数,原方法调用被限流/降级/系统保护的时候调用
public User blockHandlerForGetUser(String id, BlockException ex) {
    return new User("admin");
}

注意 blockHandler 函数会在原方法被限流/降级/系统保护的时候调用,而 fallback 函数会针对所有类型的异常。请注意 blockHandler 和 fallback 函数的形式要求。

5、异步调用支持

Sentinel 支持异步调用链路的统计。在异步调用中,需要通过 SphU.asyncEntry(xxx) 方法定义资源,并通常需要在异步的回调函数中调用 exit 方法。以下是一个简单的示例:

try {
    AsyncEntry entry = SphU.asyncEntry(resourceName);
    // 异步调用.
    doAsync(userId, result -> {
        try {
            // 在此处处理异步调用的结果.
        } finally {
            // 在回调结束后 exit.
            entry.exit();
        }
    });
} catch (BlockException ex) {
    // Request blocked.
    // Handle the exception (e.g. retry or fallback).
}


规则定义

规则种类

流量控制规则、熔断降级规则、系统保护规则、来源访问控制规则 和 热点参数规则。

1、流量控制规则

Field说明默认值
resource资源名
count限流阀值
grade阀值类型:QPS1或并发线程模式0QPS
limitApp调用来源default,代表不区分调用来源
strategy

策略:直接、链路、关联

直接(默认):接口达到限流条件时,开启限流

关联:当关联的资源达到限流条件时,开启限流,适合做应用让步。例如为一个查询的接口添加关联流控,关联资源为一个更新的接口,当更新的接口达到阈值时,开启查询接口的限流,为更新接口让步服务器资源。

链路:当从某个接口过来的资源达到限流条件时,开启限流

根据资源本身(直接)
controlBehavior
流控效果直接拒绝
clusterMode是否集群限流

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

编码加载:

private void initFlowQpsRule() {
    List<FlowRule> rules = new ArrayList<>();
    FlowRule rule = new FlowRule(resourceName);
    // set limit qps to 20
    rule.setCount(20);
    rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
    rule.setLimitApp("default");
    rules.add(rule);
    FlowRuleManager.loadRules(rules);
}

2、熔断降级

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

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

private void initDegradeRule() {    
 List<DegradeRule> rules = new ArrayList<>();    
 DegradeRule rule = new DegradeRule();    
 rule.setResource(KEY);    
 // set threshold RT, 10 ms    
 rule.setCount(10);    
 rule.setGrade(RuleConstant.DEGRADE_GRADE_RT);    
 rule.setTimeWindow(10);    
 rules.add(rule);    
 DegradeRuleManager.loadRules(rules);
}

3、系统保护规则

Field说明默认值
highestSystemLoadload1 触发值,用于触发自适应控制阶段-1不生效
avgRt所有入口流量的平均响应时间-1不生效
maxThread入口流量的最大并发数-1不生效
qps
所有入口资源的 QPS-1不生效
highestCpuUsage当前系统的 CPU 使用率(0.0-1.0)-1不生效
private void initSystemRule() {
    List<SystemRule> rules = new ArrayList<>();
    SystemRule rule = new SystemRule();
    rule.setHighestSystemLoad(10);
    rules.add(rule);
    SystemRuleManager.loadRules(rules);
}

注意系统规则只针对入口资源(EntryType=IN)生效

4、访问控制规则

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

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

resource:资源名,即规则的作用对象

limitApp:对应的黑名单/白名单,不同 origin 用 , 分隔,如 appA,appB

strategy:限制模式,AUTHORITY_WHITE 为白名单模式,AUTHORITY_BLACK 为黑名单模式,默认为白名单模式

5、热点规则


限流异常

流控异常:FlowException

熔断降级异常:DegradeException

系统保护异常:SystemBlockException

热点参数限流异常:ParamFlowException