This is the 5th day of my participation in the August More Text Challenge


Sentinel is a micro-service component provided by SpringCloud Alibaba, which can protect the stability of the service from multiple dimensions such as flow control, fuse downgrading and system load protection. Sentinel has more fusible downgrading dimensions than Hystrix, is lighter and more flexible, and has been widely used in production environments since Hystrix has stopped maintenance. As a basis for Sentinel use, this article looks at how rules should be configured.

First introduce core dependencies in poM:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
Copy the code

In a Service, annotation-based methods are defined for demoting and throwing exceptions:

@Service
public class QueryService {
    private static final String KEY="query";
    
    @SentinelResource(value = KEY,blockHandler ="blockHandlerMethod", fallback = "fallbackMethod")
    public String query(String name) {
        if(name.equals("3")) {throw new RuntimeException("3 error");
        }
        return "begin query method, name= " + name;
    }
    
    public String blockHandlerMethod(String name, BlockException e){
        e.printStackTrace();
        return "blockHandlerMethod for Query : " + name;
    }

    public String fallbackMethod(String name, Throwable e){
        e.printStackTrace();
        return "fallbackMethod for Query : "+ name; }}Copy the code

In the example above, the demotion method is specified through the blockHandler attribute of the @SentinelResource annotation, and the method when an exception is thrown is specified through the Fallback attribute. The following describes the definition methods of three rules.

1. Direct coding

Start by defining a configuration class for loading rules. In Sentinel, five rules can be customized:

  • Flow control ruleFlowRule
  • Fuse downgrading rulesDegradeRule
  • Access control rulesAuthorityRule
  • System Protection RulesSystemRule
  • Hot rulesParamFlowRule
@Component
public class SentinelConfig {
    private static final String KEY="query";
    @PostConstruct
    private void init(a){
        initDegradeRule();
        initFlowQpsRule();
        initSystemRule();
        initAuthorityRule();
        initParamFlowRule();
    }

    // Fuse downgrade rule
    private void initDegradeRule(a){
        List<DegradeRule> rules=new ArrayList<>();
        DegradeRule rule=new DegradeRule();
        rule.setResource(KEY);
        // Fuse the interface when the number of times exceeding 5 was abnormal during the 80s
        rule.setCount(5);
        rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);
        rule.setTimeWindow(80);
        rules.add(rule);
        DegradeRuleManager.loadRules(rules);
    }

    // Flow control rule
    private void initFlowQpsRule(a) {
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule = new FlowRule(KEY);
        rule.setCount(20);
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule.setLimitApp("default");
        rules.add(rule);
        FlowRuleManager.loadRules(rules);
    }

    // System protection rules
    private void initSystemRule(a) {
        List<SystemRule> rules = new ArrayList<>();
        SystemRule rule = new SystemRule();
        rule.setHighestSystemLoad(10);
        rules.add(rule);
        SystemRuleManager.loadRules(rules);
    }

    // Whitelist control
    private void initAuthorityRule(a){
        List<AuthorityRule> rules=new ArrayList<>();

        AuthorityRule rule = new AuthorityRule();
        rule.setResource(KEY);
        rule.setStrategy(RuleConstant.AUTHORITY_BLACK);
        rule.setLimitApp("nacos-consumer");
        rules.add(rule);
        AuthorityRuleManager.loadRules(rules);
    }

    // Hotspot parameter rules
    private void initParamFlowRule(a){
        ParamFlowRule rule = new ParamFlowRule(KEY)
                .setParamIdx(0)
                .setCount(20);    
        ParamFlowItem item = new ParamFlowItem().setObject(String.valueOf("4"))
                .setClassType(String.class.getName())
                .setCount(2); rule.setParamFlowItemList(Collections.singletonList(item)); ParamFlowRuleManager.loadRules(Collections.singletonList(rule)); }}Copy the code

Configure the sentinel-Dashboard address in YML:

spring:
  cloud:
    sentinel:
      transport:
        port: 8719 
        dashboard: localhost:8088 #sentinel console address
Copy the code

Start the sentinel – dashboard:

java -Dserver.port=8088 -jar sentinel-dashboard-1.8.0.jar
Copy the code

By invoking an interface, you can monitor the interface invocation status on the Dashboard Web page:

View flow control rules and trigger quick failure when QPS is 2:

Check the degradation rules and fuse when the number of anomalies exceeds 5:

2. Configure data sources using local files

Sentinel supports a variety of different data sources to configure rules, including the following methods:

  • Configuration file
  • Nacos configuration
  • ZooKeeper configuration
  • Apollo configuration

In some cases, if the configuration rules do not need to be stored on other components such as NACOS, and the rules do not change often, we can save the configuration rules in local configuration files.

Create class FileDataSourceInit to read configuration files:

public class FileDataSourceInit implements InitFunc {
    private Converter<String, List<FlowRule>> flowRuleListParser = source -> JSON.parseObject(source,
            new TypeReference<List<FlowRule>>() {});
    private Converter<String, List<DegradeRule>> degradeRuleListParser = source -> JSON.parseObject(source,
            new TypeReference<List<DegradeRule>>() {});
    private Converter<String, List<SystemRule>> systemRuleListParser = source -> JSON.parseObject(source,
            new TypeReference<List<SystemRule>>() {});
    private Converter<String, List<ParamFlowRule>> paramFlowRuleListParser = source -> JSON.parseObject(source,
            new TypeReference<List<ParamFlowRule>>() {});
    private Converter<String, List<AuthorityRule>> authorityRuleListParser = source -> JSON.parseObject(source,
            new TypeReference<List<AuthorityRule>>() {});

    @Override
    public void init(a) throws Exception {
        ClassLoader classLoader = getClass().getClassLoader();
        String flowRulePath = URLDecoder.decode(classLoader.getResource("rules/flowRule.json").getFile(), "UTF-8");
        String degradeRulePath = URLDecoder.decode(classLoader.getResource("rules/degradeRule.json").getFile(), "UTF-8");
        String systemRulePath = URLDecoder.decode(classLoader.getResource("rules/systemRule.json").getFile(), "UTF-8");
        String paramFlowRulePath = URLDecoder.decode(classLoader.getResource("rules/paramFlowRule.json").getFile(), "UTF-8");
        String authorityRulePath = URLDecoder.decode(classLoader.getResource("rules/authorityRule.json").getFile(), "UTF-8");

        // Data source for FlowRule
        FileRefreshableDataSource<List<FlowRule>> flowRuleDataSource = new FileRefreshableDataSource<>(
                flowRulePath, flowRuleListParser);
        FlowRuleManager.register2Property(flowRuleDataSource.getProperty());

        // Data source for DegradeRule
        FileRefreshableDataSource<List<DegradeRule>> degradeRuleDataSource
                = new FileRefreshableDataSource<>(
                degradeRulePath, degradeRuleListParser);
        DegradeRuleManager.register2Property(degradeRuleDataSource.getProperty());

        // Data source for SystemRule
        FileRefreshableDataSource<List<SystemRule>> systemRuleDataSource
                = new FileRefreshableDataSource<>(
                systemRulePath, systemRuleListParser);
        SystemRuleManager.register2Property(systemRuleDataSource.getProperty());

        // Data source for ParamFlowRule
        FileRefreshableDataSource<List<ParamFlowRule>> paramFlowRuleDataSource
                = new FileRefreshableDataSource<>(
                paramFlowRulePath, paramFlowRuleListParser);
        ParamFlowRuleManager.register2Property(paramFlowRuleDataSource.getProperty());

        // Data source for AuthorityRule
        FileRefreshableDataSource<List<AuthorityRule>> authorityRuleDataSource
                = newFileRefreshableDataSource<>( authorityRulePath, authorityRuleListParser); AuthorityRuleManager.register2Property(authorityRuleDataSource.getProperty()); }}Copy the code

Based on the SPI extension mechanism, under the resources to create a meta-inf/services directory, create a file com. Alibaba. CSP. Sentinel. Init. InitFunc, fill in the above class inside the fully qualified name:

com.cn.config.FileDataSourceInit
Copy the code

Create the rules directory under Resources to save the JSON file of the configuration rules. The following uses flowrule-json as an example:

[{"resource":"query"."limitApp":"default"."grade":"1"."count":"2"."strategy":0."controlBehavior":2."clusterMode":false}]Copy the code

Above is a JSON array in which each object is a configuration object for each protected resource. Explain the meaning of the above parameters:

Resource: indicates the name of the resource
LimitApp: Source app
Grade: indicates the threshold type. 0 indicates the number of threads and 1 indicates QPS
Count: single-machine threshold
Strategy: flow control mode. 0 indicates direct, 1 indicates association, and 2 indicates link
ControlBehavior: Flow control effect. 0 indicates fast failure and 1 indicates warm Up, 2: queuing
ClusterMode: Indicates whether to cluster
Copy the code

For other Rule parameters, refer to the attributes in the source code of each Rule in the first method. Change the first letter to lowercase, which corresponds to the attribute name in JSON. Thus, the rules in the configuration file can be loaded into memory through the SPI extension mechanism.

3. Configure the data source using NACOS

When reading the official documentation, it is found that the official recommendation is to use NACOS as the data source, and the dependency of nacOS storage extension needs to be imported:

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
    <version>1.8.0 comes with</version>
</dependency>
Copy the code

Add configuration information to YML to configure NACOS as the data source:

spring:
  cloud:
    sentinel:
      transport:
        port: 8719  
        dashboard: localhost:8088 
      datasource:
        ds:
          nacos:
            server-addr: 127.0. 01.: 8848 
            group-id: DEFAULT_GROUP
            rule-type: flow 
            data-id: sentinel-demo-getSentinelConfig
            data-type: json
Copy the code

Data source parameter meaning:

Server-addr: nacOS connection address group-id: nacOS connection group rule-type: specifies the routing storage rule data-id: indicates the data-id that reads the configuration file data-type: specifies the routing storage rule. Specifies the type of configuration file to readCopy the code

Add the configuration information of a flow control rule to the configuration list of NACOS:

Corresponding to the application. Yml of the project, data-id is sentinel-Demo-getSentinelConfig, and group-id is DEFAULT_GROUP.

Refresh the Dashboard flow control page and you can see that the new rule has been pushed:

If you change the contents of the configuration file in NACOS, the rules are pushed to dashboard and the in-memory rules are updated accordingly. In this way, compared with the previous two configurations, the non-stop update rule is implemented. After the integration, changes to the rules can be made in sentinel-Dashboard and NACOS at the same time.

However, there are still some problems that need to be noted:

  • The rules set by Dashboard are in memory and disappear once you restart
  • Rules can only be passed to Dashboard through NACOS, not written to NACOS or local configuration files, i.e. rule delivery is one-way

To recap, since the rules in nacOS or configuration files are persistent and not in memory, is it possible to store the rules configured in Dashboard? In the next article, we’ll look at how to persist rules.

The last

If you feel helpful, friends can like, forward it, thank you very much for the public number nongshen, to add a friend, do a like friend