前面咱们都是直接经过集成sentinel的依赖,经过编码的方式配置规则等。对于集成到Spring Cloud中阿里已经有了一套开源框架spring-cloud-alibaba,就是用于将一系列的框架成功的整合到Spring Cloud中。spring
我这边Spring Cloud的版本是Finchley.SR2,Spring Boot的版本是2.0.6.RELEASE,下面开始集成步骤。json
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <version>0.2.1.RELEASE</version> </dependency>
application.properties微信
# 文件规则数据源 spring.cloud.sentinel.datasource.ds1.file.file=classpath: flowrule.json # JSON格式的数据 spring.cloud.sentinel.datasource.ds1.file.data-type=json # 规则类型 spring.cloud.sentinel.datasource.ds1.file.rule-type=flow
flowrule.jsonapp
[ { "resource": "hello", "controlBehavior": 0, "count": 1, "grade": 1, "limitApp": "default", "strategy": 0 } ]
@GetMapping("/test") @SentinelResource(value="hello",blockHandler="handleException",blockHandlerClass=ExceptionUtil.class) public String test() { String result = restTemplate.getForObject("http://localhost:8087/user/name", String.class); return result; }
public class ExceptionUtil { public static String handleException(BlockException ex) { return "扛不住了啊...."; } }
前面咱们使用注解的话都是手动配置SentinelResourceAspect类,为何今天不须要配置SentinelResourceAspect呢?框架
那是由于在spring-cloud-alibaba中已经默认配置好了,代码在org.springframework.cloud.alibaba.sentinel.custom.SentinelAutoConfiguration中,代码以下:学习
@Bean @ConditionalOnMissingBean public SentinelResourceAspect sentinelResourceAspect() { return new SentinelResourceAspect(); }
利用spring-cloud-alibaba整合Apollo就比较简单了,直接经过配置就能够,不须要经过编码的方式手动注册动态数据源。测试
<dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-apollo</artifactId> <version>1.4.1</version> </dependency>
# Apollo命名空间 spring.cloud.sentinel.datasource.ds4.apollo.namespace-name = application # 规则配置Key spring.cloud.sentinel.datasource.ds4.apollo.flow-rules-key = flowRules # 规则配置默认值 spring.cloud.sentinel.datasource.ds4.apollo.default-flow-rule-value = [] # 规则类型 spring.cloud.sentinel.datasource.ds4.apollo.rule-type = flow
关于Apollo的地址,appid等信息能够在配置文件中添加,咱们为了演示方便就仍是使用代码指定的方式。编码
@SpringBootApplication public class SentinelApp { public static void main(String[] args) { // Apollo 中的应用名称,本身定义的 String appId = "SampleApp"; // Apollo 的地址 String apolloMetaServerAddress = "http://localhost:8080"; System.setProperty("app.id", appId); System.setProperty("apollo.meta", apolloMetaServerAddress); // 指定环境 System.setProperty("env", "DEV"); SpringApplication.run(SentinelApp.class, args); } }
在Apollo中添加限流的规则便可,好比:spa
flowRules = [{"grade":1,"count":1,"resource":"hello","controlBehavior":0}]
在org.springframework.cloud.alibaba.sentinel.datasource.converter.JsonConverter中打个端点调试下,启动时或者配置更新时都会在里面进行规则的转换。调试
在这边遇到了一个坑跟你们分享一下,最开始我配置了最简单的规则,就下面三个Key
flowRules = [{"grade":1,"count":1,"resource":"hello"}]
若是配置成上面的三个Key,限流将不会触发,后面本身调试JsonConverter中的代码才发现了缘由。
有这么一段代码,是根据配置中心的json字符串转换成对应的规则类:
List<AbstractRule> rules = Arrays.asList(convertFlowRule(itemJson), convertDegradeRule(itemJson), convertSystemRule(itemJson), convertAuthorityRule(itemJson), convertParamFlowRule(itemJson));
转换完了后会进行过滤,获得一个最终的List,而后判断数量,只有为1的时候才是正确的,因为我配置上面的规则,而后得出来的convertRuleList里面数量为2,这样就无法返回正确的规则。
List<AbstractRule> convertRuleList = rules.stream() .filter(rule -> !ObjectUtils.isEmpty(rule)) .collect(Collectors.toList()); if (convertRuleList.size() == 0) { logger.warn( "Sentinel JsonConverter can not convert {} to any rules, ignore", itemJson); } else if (convertRuleList.size() > 1) { logger.warn( "Sentinel JsonConverter convert {} and match multi rules, ignore", itemJson); } else { ruleList.add(convertRuleList.get(0)); }
之全部数量为2是由于上面转换代码的convertFlowRule(itemJson)和convertParamFlowRule(itemJson),这两个转换的问题,因为个人配置只有三个key,而这三个Key又是这两个规则共同的,因此都转换成功了才致使数量为2。解决办法就是加一些独有的Key,好比controlBehavior。
固然这个问题若是咱们对接了控制台的话,经过控制台去修改配置中心的值就不会出现这个问题了。但这也是在学习过程当中遇到的一个问题,仍是得经过调试源码的方式去发现问题的缘由。