前面咱們都是直接經過集成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中,代碼以下:maven
@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中添加限流的規則便可,好比:編碼
flowRules = [{"grade":1,"count":1,"resource":"hello","controlBehavior":0}]
在org.springframework.cloud.alibaba.sentinel.datasource.converter.JsonConverter中打個端點調試下,啓動時或者配置更新時都會在裏面進行規則的轉換。spa
在這邊遇到了一個坑跟你們分享一下,最開始我配置了最簡單的規則,就下面三個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。
固然這個問題若是咱們對接了控制檯的話,經過控制檯去修改配置中心的值就不會出現這個問題了。但這也是在學習過程當中遇到的一個問題,仍是得經過調試源碼的方式去發現問題的緣由。