Previously, we used to integrate sentinel dependencies directly, configure rules by encoding, and so on. Ali already has an open source framework spring-cloud-alibaba for integration into Spring Cloud, which is used to successfully integrate a series of frameworks into Spring Cloud.
My version of Spring Cloud is Finchley.SR2, and Spring Boot is 2.0.6.RELEASE. Let's start the integration step.
1. Integration steps
1.1 Adding Maven Dependencies
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <version>0.2.1.RELEASE</version> </dependency>
1.2 Configuration of Increasing Current Limitation
application.properties
# File Rule Data Source spring.cloud.sentinel.datasource.ds1.file.file=classpath: flowrule.json # Data in JSON format spring.cloud.sentinel.datasource.ds1.file.data-type=json # Rule type spring.cloud.sentinel.datasource.ds1.file.rule-type=flow
flowrule.json
[ { "resource": "hello", "controlBehavior": 0, "count": 1, "grade": 1, "limitApp": "default", "strategy": 0 } ]
1.3 @Sentinel Resource uses
@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; }
1.4 Definition of Backward Content
public class ExceptionUtil { public static String handleException(BlockException ex) { return "I can't carry it anymore....."; } }
The SentinelResourceAspect class was manually configured in the previous annotations. Why don't we need to configure SentinelResourceAspect today?
That's because spring-cloud-alibaba has been configured by default. The code is in org. spring framework. cloud. alibaba. sentinel. custom. Sentinel AutoConfiguration. The code is as follows:
@Bean @ConditionalOnMissingBean public SentinelResourceAspect sentinelResourceAspect() { return new SentinelResourceAspect(); }
2. Integrating Apollo persistence rules
Using spring-cloud-alibaba to integrate Apollo is relatively simple. It can be configured directly without manual registration of dynamic data sources by encoding.
2.1 Increasing Apollo's Maven Dependence
<dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-apollo</artifactId> <version>1.4.1</version> </dependency>
2.2 Data Source Configuration
# Apollo namespace spring.cloud.sentinel.datasource.ds4.apollo.namespace-name = application # Rule Configuration Key spring.cloud.sentinel.datasource.ds4.apollo.flow-rules-key = flowRules # Rule Configuration Default spring.cloud.sentinel.datasource.ds4.apollo.default-flow-rule-value = [] # Rule type spring.cloud.sentinel.datasource.ds4.apollo.rule-type = flow
2.3 Apollo-related configuration
Information about Apollo's address, appid, etc. can be added to the configuration file. For demonstration convenience, we still use code-specified methods.
@SpringBootApplication public class SentinelApp { public static void main(String[] args) { // Apollo's application name, self-defined String appId = "SampleApp"; // Address of Apollo String apolloMetaServerAddress = "http://localhost:8080"; System.setProperty("app.id", appId); System.setProperty("apollo.meta", apolloMetaServerAddress); // Designated environment System.setProperty("env", "DEV"); SpringApplication.run(SentinelApp.class, args); } }
2.4 test
Add current-limiting rules to Apollo, such as:
flowRules = [{"grade":1,"count":1,"resource":"hello","controlBehavior":0}]
With an endpoint debugging in org. spring framework. cloud. alibaba. sentinel. datasource. converter. JsonConverter, rules are converted at startup or configuration updates.
I met a pit here to share with you. At first, I configured the simplest rules. Here are three keys.
flowRules = [{"grade":1,"count":1,"resource":"hello"}]
If you configure the three keys above, the current limit will not trigger, and later you debug the code in JsonConverter to find out why.
There is a code that converts the json string of the configuration center into the corresponding rule class:
List<AbstractRule> rules = Arrays.asList(convertFlowRule(itemJson), convertDegradeRule(itemJson), convertSystemRule(itemJson), convertAuthorityRule(itemJson), convertParamFlowRule(itemJson));
After the conversion, it will be filtered to get a final List, and then judge the number, only when it is 1, because I configure the rules above, and then get the number of convertRuleList is 2, so I can not return the correct rules.
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)); }
The number of 2 is due to the convertFlowRule(itemJson) and convertParamFlowRule(itemJson) of the above conversion code. Because my configuration only has three keys, and these three keys are the same rules, the number of 2 is due to the successful conversion. The solution is to add some unique keys, such as controlBehavior.
Of course, if we dock with the console, this problem will not arise if we use the console to modify the value of the configuration center. But this is also a problem encountered in the learning process, or we have to debug the source code to find the cause of the problem.