【SpringCloudAlibaba系列】分布式限流框架Sentinel定义资源方式及资源保护规则| 8月更文挑战

537 阅读2分钟

这是我参与8月更文挑战的第4天,活动详情查看: 8月更文挑战

Sentinel定义资源方式及资源保护规则

资源的定义方式
  1. 通过返回布尔值的方式定义资源 SphO提供if-else风格的API,用这种方式,来判断资源是否发生限流,发生限流则返回false,可根据对应返回值,进行限流处理
if(SphO.entry("doLimiting")){
            try{
                //业务逻辑
                log.info("{}-doLimiting",System.currentTimeMillis());
            }finally {
                SphO.exit();
            }
        }else {
            //处理被流量控制的逻辑
        }

使用这种方式,需要注意资源使用完后调用Sph0.exit(),否则会导致调用链记录异常,抛出ErrorEntryFreeException异常

  1. Sentinel使用@SentinelResource注解方式定义资源
@SentinelResource(value = "doLimitingByAnnotation",blockHandler = "blockHandlerByName")
@RequestMapping("limit")
public void doLimitingByAnnotation(String name){
        //业务逻辑
        log.info("name:{}",name);
        throw new RuntimeException("doLimitingByAnnotation command failed");
}

public  void blockHandlerByName(String name,BlockException e){
        //被限流后的处理方法
        User user = new User();
        user.setName("Gxin");
        log.info("user:{}",user.toString());
    }

注意点:

blockHandler所配置的值blockHandlerByName方法会在触发限流后调用,这个方法的定义必须和原始方法的返回值、参数保持一致,而且需要增加BlockException参数,另外fallback 函数会针对所有类型的异常,注意blockHandler和fallback函数使用形式不同

3.异步调用支持

Sentinel支持异步调用链路统计

public void doLimitingByAsync(String name) {
        try {
            AsyncEntry entry = SphU.asyncEntry("doLimiting");
            CompletableFuture.runAsync(() -> {
                //异步回调进行上下文切换,通过entry的getAsyncContext方法获取异步Context
                ContextUtil.runOnContext(entry.getAsyncContext(), () -> {
                    try {
                        //处理异步调用的结果
                        String result = entry.getAsyncContext().getName();
                        Thread.sleep(3000);
                        log.info("Async Entry Name:{}",result);
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    } finally {
                        entry.exit();
                    }
                });
            });
        } catch (BlockException e) {

        }
    }
Sentinel资源保护规则

Sentinel支持多种保护规则:

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

通过FlowRule定义限流规则,再使用FlowRuleManager.loadRules来加载规则列表,具体实现如下

private static void initFlowRules(){
        List<FlowRule> flowRules = new ArrayList<>();
        FlowRule flowRule = new FlowRule();
        flowRule.setResource("doLimiting");
        flowRule.setCount(20);
        flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        flowRule.setClusterMode(false);
        flowRule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT);
        flowRule.setStrategy(RuleConstant.STRATEGY_CHAIN);
        flowRule.setLimitApp("default");
        flowRules.add(flowRule);
        FlowRuleManager.loadRules(flowRules);
    }

FlowRule部分属性含义如下:

  • limitApp:是否需要针对调用来源进行限流,默认是default,即不区分调用来源
  • strategy:调用关系限流策略-直接、关联、链路
  • controllerBehavior:流控行为,包括直接拒绝、排队等待、慢启动模式,默认是直接拒绝
  • clusterMode: 是否集群限流,默认为否