这是我参与8月更文挑战的第4天,活动详情查看: 8月更文挑战
Sentinel定义资源方式及资源保护规则
资源的定义方式
- 通过返回布尔值的方式定义资源 SphO提供if-else风格的API,用这种方式,来判断资源是否发生限流,发生限流则返回false,可根据对应返回值,进行限流处理
if(SphO.entry("doLimiting")){
try{
//业务逻辑
log.info("{}-doLimiting",System.currentTimeMillis());
}finally {
SphO.exit();
}
}else {
//处理被流量控制的逻辑
}
使用这种方式,需要注意资源使用完后调用Sph0.exit(),否则会导致调用链记录异常,抛出ErrorEntryFreeException异常
- 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: 是否集群限流,默认为否