Sentinel sentinel integrates Gateway to realize Gateway flow control console and rule configuration

1. Introduction

The gateway is the common entrance for all requests, so the current can be limited in the gateway, and there are many ways to limit the current. The current limit of the gateway is realized through sentinel component. Sentinel supports current limiting for spring cloud gateway, Zuul and other mainstream gateways.

The current limiting mechanism is mainly configured by two core classes, GatewayFlowRule and ApiDefinition:

  • GatewayFlowRule: gateway flow restriction rule, which is customized for the scenario of API Gateway. It can limit the flow for different route s or customized API groups. It supports customized flow restriction for parameters, headers, source IP, etc. in the request.
  • ApiDefinition: user defined API definition grouping, which can be regarded as a combination of URL matching. For example, we can define an API called my_api, all requests with path modes of / foo / * * and / baz / * * belong to my_api this API is grouped below. When limiting flow, you can limit flow for this customized API grouping dimension.

The fields of gateway current limiting rule GatewayFlowRule are explained as follows:

  • Resource: resource name, which can be the route name in the gateway or the user-defined API group name.
  • resourceMode: whether the rule is for the route (RESOURCE_MODE_ROUTE_ID) of the API Gateway or the API Group (RESOURCE_MODE_CUSTOM_API_NAME) defined by the user in Sentinel. The default is route.
  • Grade: current limit indicator dimension, the same as the grade field of current limit rules.
  • count: current limiting threshold
  • intervalSec: Statistics time window. The unit is seconds. The default is 1 second.
  • controlBehavior: the control effect of traffic shaping is the same as that of the controlBehavior field of flow restriction rules. At present, it supports two modes: fast failure and uniform queuing. The default is fast failure.
  • burst: the number of additional requests allowed in response to sudden requests.
  • maxQueueingTimeoutMs: the longest queuing time under the uniform queuing mode. The unit is milliseconds. It only takes effect under the uniform queuing mode.
  • paramItem: parameter current limiting configuration. If it is not provided, it means that the current is not limited for the parameters, and the gateway rule will be converted into a common flow control rule; Otherwise, it will be converted to hotspot rules. Fields:
    • parseStrategy: the strategy of extracting parameters from the request. At present, it supports four modes: extracting source IP (PARAM_PARSE_STRATEGY_CLIENT_IP), Host (PARAM_PARSE_STRATEGY_HOST), arbitrary Header (PARAM_PARSE_STRATEGY_HEADER) and arbitrary URL parameters (PARAM_PARSE_STRATEGY_URL_PARAM).
    • fieldName: if the extraction policy selects header mode or URL parameter mode, you need to specify the corresponding header name or URL parameter name.
    • Pattern: the matching pattern of parameter values. Only the request attribute values matching the pattern will be included in statistics and flow control; If it is blank, all values of the request attribute will be counted. (supported from version 1.6.2)
    • matchStrategy: the matching strategy of parameter values. At present, it supports exact matching (param_match_strategy_act), substring matching (PARAM_MATCH_STRATEGY_CONTAINS) and regular matching (PARAM_MATCH_STRATEGY_REGEX). (supported from version 1.6.2)

Sentinel provides two current limiting modes

  • Route dimension: the route entry configured in the Spring configuration file. The resource name is the corresponding routeId
  • Custom API dimension: users can use the API provided by Sentinel to customize some API groups

2. Routing dimension current limiting

Introducing POM:

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
</dependency>

yaml configuration:

spring:
  cloud: 
    gateway:
      routes: 
        - id: user-service # Routing id
          uri: lb://User service # jumps to the uri path of the service
          predicates:
            - Path=/user/** 

Gateway configuration file creation:

@Configuration
public class GatewayConfiguration {
    private final List<ViewResolver> viewResolvers;
    private final ServerCodecConfigurer serverCodecConfigurer;

    public GatewayConfiguration(ObjectProvider<List<ViewResolver>> viewResolversProvider, ServerCodecConfigurer serverCodecConfigurer) {
        this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
        this.serverCodecConfigurer = serverCodecConfigurer;
    }

    /**
     * Initialize a current limiting filter
     *
     * @return
     */
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public GlobalFilter sentinelGatewayFilter() {
        return new SentinelGatewayFilter();
    }

    /**
     * Configure current limiting exception handler
     *
     * @return
     */
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public SentinelGatewayBlockExceptionHandler
    sentinelGatewayBlockExceptionHandler() {
        return new SentinelGatewayBlockExceptionHandler(viewResolvers,
                serverCodecConfigurer);
    }

    /**
     * Loading rules
     */
    @PostConstruct
    public void doInit() {
        initGatewayRules();
    }
	
	/**
     * Configure initialized current limiting parameters
     */
    public void initGatewayRules() {
        Set<GatewayFlowRule> rules = new HashSet<>();
        // Routing id configured in yaml
        rules.add(new GatewayFlowRule("user-service")
 		        // Current limiting dimension
        		.setResourceMode(SentinelGatewayConstants.RESOURCE_MODE_ROUTE_ID)
                // Current limiting threshold
                .setCount(1)
                // time window
                .setIntervalSec(1)
                // Hot spot current limit is being applied to the request parameters
                .setParamItem(new GatewayParamFlowItem()
			            .setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_URL_PARAM)
                        // Parameter name
                        .setFieldName("pa")
                )
        );
        GatewayRuleManager.loadRules(rules);
    }
}

The flow restriction rule represented by the above configuration is: when the route ID is user service and there is a parameter called pa in the requested URL, the maximum concurrency is 1 in 1 second.

We can also not configure setParamItem(), so the rule is: when entering all requests with routing ID of user service, the maximum concurrency is 1 in 1 second.

Of course, setParamItem() also has many flow restriction rules, such as Header parameter

Test:
We initiate two requests, for example: user/list?pa=123 and user/list, simulate concurrency by quickly refreshing the browser.

Conclusion: for requests with pa parameters, Sentinel current limit will appear for continuous access, while requests without pa parameters will not be triggered.

3. API dimension current limiting

It provides a more detailed current limiting matching mechanism, which can realize current limiting for some requests.

Introducing POM:

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
</dependency>

yaml configuration:

spring:
  cloud: 
    gateway:
      routes: 
        - id: user-service # Routing id
          uri: lb://User service # jumps to the uri path of the service
          predicates:
            - Path=/user/** 
		- id: wage-service # Routing id
          uri: lb://Jump service path # of wave uri
          predicates:
            - Path=/wage/** 

To create a GatewayConfiguration profile:

@Configuration
public class GatewayConfiguration {
    private final List<ViewResolver> viewResolvers;
    private final ServerCodecConfigurer serverCodecConfigurer;

    public GatewayConfiguration(ObjectProvider<List<ViewResolver>> viewResolversProvider, ServerCodecConfigurer serverCodecConfigurer) {
        this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
        this.serverCodecConfigurer = serverCodecConfigurer;
    }

    /**
     * Initialize a current limiting filter
     *
     * @return
     */
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public GlobalFilter sentinelGatewayFilter() {
        return new SentinelGatewayFilter();
    }

    /**
     * Configure current limiting exception handler
     *
     * @return
     */
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public SentinelGatewayBlockExceptionHandler
    sentinelGatewayBlockExceptionHandler() {
        return new SentinelGatewayBlockExceptionHandler(viewResolvers,
                serverCodecConfigurer);
    }


    /**
     * Loading rules
     */
    @PostConstruct
    public void doInit() {
        initCustomizedApis();
        initGatewayRules();
    }

    /**
     * Custom API grouping
     */
    private void initCustomizedApis() {
        Set<ApiDefinition> definitions = new HashSet<>();
        //Set the group name, which is consistent with the group name in new GatewayFlowRule()
        ApiDefinition api1 = new ApiDefinition("user-service-api")
                .setPredicateItems(new HashSet<ApiPredicateItem>() {{
                    //Set rules
                    //Requests starting with / user
					add(new ApiPathPredicateItem().setPattern("/user/list/**").     
  		                    setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
                    //Full path matching
                    add(new ApiPathPredicateItem().setPattern("/user/role"));
                }});
        ApiDefinition api2 = new ApiDefinition("wage-service-api")
                .setPredicateItems(new HashSet<ApiPredicateItem>() {{
                    add(new ApiPathPredicateItem().setPattern("/wage/**").
                            setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
                }});
        definitions.add(api1);
        definitions.add(api2);
        GatewayApiDefinitionManager.loadApiDefinitions(definitions);
    }

    /**
     * Configure initialized current limiting parameters
     */
    public void initGatewayRules() {
        Set<GatewayFlowRule> rules = new HashSet<>();
        // Set the api group name, any name
        rules.add(new GatewayFlowRule("user-service-api")
                .setResourceMode(SentinelGatewayConstants.RESOURCE_MODE_CUSTOM_API_NAME)
                // Current limiting threshold
                .setCount(1)
                // time window
                .setIntervalSec(1)
        );
        // Set the api group name, any name
        rules.add(new GatewayFlowRule("wage-service-api")
                .setResourceMode(SentinelGatewayConstants.RESOURCE_MODE_CUSTOM_API_NAME)
                // Current limiting threshold
                .setCount(2)
                // time window
                .setIntervalSec(1)
        );
        GatewayRuleManager.loadRules(rules);
    }
}

The current limiting rules represented by the above configuration are:

  • When the request starts with / wave / * * the wave service API flow limiting rule will be triggered. Within one second, the maximum number of concurrent requests is 2.

  • When the request starts with / user/list / * * and / user/role, the user service API flow limiting rule will be triggered. Within 1 second, the maximum number of concurrent requests is 1.

Test:

4. Comprehensive use

We can use the current limit of routing dimension and API dimension at the same time. The configuration is as follows:

@Configuration
public class GatewayConfiguration {
    private final List<ViewResolver> viewResolvers;
    private final ServerCodecConfigurer serverCodecConfigurer;

    public GatewayConfiguration(ObjectProvider<List<ViewResolver>> viewResolversProvider, ServerCodecConfigurer serverCodecConfigurer) {
        this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
        this.serverCodecConfigurer = serverCodecConfigurer;
    }

    /**
     * Initialize a current limiting filter
     *
     * @return
     */
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public GlobalFilter sentinelGatewayFilter() {
        return new SentinelGatewayFilter();
    }

    /**
     * Configure current limiting exception handler
     *
     * @return
     */
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public SentinelGatewayBlockExceptionHandler
    sentinelGatewayBlockExceptionHandler() {
        return new SentinelGatewayBlockExceptionHandler(viewResolvers,
                serverCodecConfigurer);
    }


    /**
     * Loading rules
     */
    @PostConstruct
    public void doInit() {
        initCustomizedApis();
        initGatewayRules();
    }

    /**
     * Custom API grouping
     */
    private void initCustomizedApis() {
        Set<ApiDefinition> definitions = new HashSet<>();
        //Set the group name, which is consistent with the group name in new GatewayFlowRule()
        ApiDefinition api1 = new ApiDefinition("user-service-api")
                .setPredicateItems(new HashSet<ApiPredicateItem>() {{
                    //Set rules
                    //Requests starting with / user
                    add(new ApiPathPredicateItem().setPattern("/user/list/**").
                            setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
                    //Full path matching
                    add(new ApiPathPredicateItem().setPattern("/user/role"));
                }});
        definitions.add(api1);
        GatewayApiDefinitionManager.loadApiDefinitions(definitions);
    }


    /**
     * Configure initialized current limiting parameters
     */
    public void initGatewayRules() {
        Set<GatewayFlowRule> rules = new HashSet<>();
        // Set the current limit of the routing dimension
        rules.add(new GatewayFlowRule("user-service")
                .setResourceMode(SentinelGatewayConstants.RESOURCE_MODE_ROUTE_ID)
                // Current limiting threshold
                .setCount(10)
                // time window
                .setIntervalSec(1)
        );
        // Set the api group name, any name
        rules.add(new GatewayFlowRule("user-service-api")
                .setResourceMode(SentinelGatewayConstants.RESOURCE_MODE_CUSTOM_API_NAME)
                // Current limiting threshold
                .setCount(1)
                // time window
                .setIntervalSec(1)
        );
        GatewayRuleManager.loadRules(rules);
    }
}

The current limiting rules represented by the above configuration are:

  • When the request starts with user / * * it will enter the user service with the routing ID and trigger the flow restriction rule of the routing dimension. Within one second, the maximum number of concurrent requests is 10.

  • When the request starts with / user/list / * * and / user/role, the user service API flow limiting rule will be triggered. Within 1 second, the maximum number of concurrent requests is 1.

If the flow restriction rules of routing dimension and API dimension are configured at the same time, the flow restriction rules of API dimension will be triggered first.

Test:

5. Implementation principle of gateway flow control

When the gateway flow control rule is loaded through the GatewayRuleManager, whether the flow is limited for the request attribute or not, Sentinel bottom layer will convert the gateway flow control rule into a hot spot parameter rule and store it in the GatewayRuleManager, which is isolated from the normal hot spot parameter rule. During conversion, Sentinel will set the parameter index (idx) for the gateway flow control rule according to the request attribute configuration, and synchronize it to the generated hotspot parameter rule.

When an external request enters the API Gateway, it will pass through the filter implemented by sentinel, which will carry out routing / API packet matching, request attribute parsing and parameter assembly in turn. Sentinel will parse the request attributes according to the configured gateway flow control rules, assemble the parameter array according to the parameter index order, and finally pass it to sphu Entry (RES, args). The Sentinel API Gateway Adapter Common module adds a GatewayFlowSlot to the Slot Chain to check the gateway rules. The parameters generated from the rules of gatewayslot will be checked according to the parameters of the rules of gatewayslot. If a rule is not specific to the request attribute, a preset constant will be placed in the last position of the parameter to achieve the effect of ordinary flow control.

6. Gateway flow control console

Users can directly view the real-time route and custom API packet monitoring of API Gateway on Sentinel console, and manage gateway rules and API packet configuration.

For other rule configurations, refer to: Sentinel console rules configuration

6.1 how to use:

When starting the Gateway module, we need to add a JVM parameter: - DCSP sentinel. app. Type = 1, for example:

java -jar `-Dcsp.sentinel.app.type=1 demo-gateway.jar

6.2 API management


The API grouping dimension defined in the GateWay code through ApiDefinition will be displayed in the API management list. We can also add API grouping through the console

6.3 flow control rules

The flow control rules will show the API flow restriction rules and routing dimension flow restriction rules defined in the GateWay code through the GatewayFlowRule. We can also add routing or API dimension flow restriction rules on the page.

6.4 degradation rules

In addition to flow control, fusing and degrading unstable resources in the call link is also one of the important measures to ensure high availability. A service often calls other modules, which may be another remote service, database, or third-party API.. However, the stability of this dependent service cannot be guaranteed. If the dependent service is unstable and the response time of the request becomes longer, the response time of the method calling the service will also become longer and the threads will accumulate, which may eventually deplete the thread pool of the business itself and make the service itself unavailable.

If a ring on a complex link is unstable, it may cascade layer by layer, resulting in the unavailability of the whole link. Therefore, we need to fuse and downgrade the unstable weak dependent service calls, temporarily cut off the unstable calls, and avoid the overall avalanche caused by local unstable factors. As a means of protecting itself, fuse degradation is usually configured on the client (caller).

Sentinel provides the following fusing strategies:

The fuse degradation rule contains the following important attributes:

FieldexplainDefault value
resourceResource name, that is, the object of the rule
gradeFusing strategy, supporting slow call proportion / abnormal proportion / different constant strategySlow call ratio
countIn slow call proportional mode, it is slow call critical RT (exceeding this value is counted as slow call); It is the corresponding threshold in the abnormal proportion / abnormal number mode
timeWindowFusing duration, unit: s
minRequestAmountThe minimum number of requests triggered by fusing. When the number of requests is less than this value, it will not fuse even if the abnormal ratio exceeds the threshold (introduced by 1.7.0)5
statIntervalMsStatistical duration (unit: ms), for example, 60 * 1000 represents minute level (introduced from 1.8.0)1000 ms
slowRatioThresholdSlow call proportion threshold, only the slow call proportion mode is valid (introduced in 1.8.0)

The same resource can have multiple degradation rules at the same time.

6.4.1 slow call ratio

Select the slow call proportion as the threshold. You need to set the allowed slow call RT (i.e. the maximum response time). If the response time of the request is greater than this value, it will be counted as slow call. When the number of requests within the unit statistical duration (statIntervalMs) is greater than the set minimum number of requests, and the proportion of slow calls is greater than the threshold, the next request within the fusing duration will be blown automatically. After fusing for a long time, the fuse will enter the detection recovery state (HALF-OPEN state). If the response time of the next request is less than the set slow call RT, the fusing will be ended. If it is greater than the set slow call RT, it will be blown again.

6.4.2 abnormal proportion

When the number of requests in the unit statistical duration (statIntervalMs) is greater than the set minimum number of requests, and the proportion of exceptions is greater than the threshold, the next request in the fusing duration will be blown automatically. After fusing for a long time, the fuse will enter the detection recovery state (HALF-OPEN state). If the next request is successfully completed (without error), the fusing will be ended, otherwise it will be blown again. The threshold range of abnormal ratio is [0.0, 1.0], representing 0% - 100%.

6.4.3 number of exceptions

When the number of exceptions in the unit statistical time exceeds the threshold, it will automatically fuse. After fusing for a long time, the fuse will enter the detection recovery state (HALF-OPEN state). If the next request is successfully completed (without error), the fusing will be ended, otherwise it will be blown again.

6.5 system rules

The system protection rule is to control the entrance flow at the application level, and monitor the application indicators from the dimensions of load, CPU utilization, average RT, entrance QPS and the number of concurrent threads of a single machine, so as to make the system run at the maximum throughput and ensure the overall stability of the system.

System protection rules apply to the overall dimension, not the resource dimension, and are only effective for inlet traffic. Portal traffic refers to the traffic entering the application, such as the requests received by Web services or Dubbo servers, which belong to portal traffic.

System rules support the following modes:

  • Load adaptation (only valid for Linux / Unix like machines): the load1 of the system is used as the heuristic index for adaptive system protection. When system load1 exceeds the set heuristic value and the current number of concurrent threads exceeds the estimated system capacity, system protection will be triggered (BBR stage). The system capacity is estimated from the maxQps * minRt of the system. The setting reference value is generally CPU cores * 2.5.
  • CPU usage (version 1.5.0 +): when the system CPU usage exceeds the threshold, the system protection is triggered (value range 0.0-1.0), which is sensitive.
  • Average RT: when the average RT of all inlet flows on a single machine reaches the threshold, the system protection is triggered, and the unit is milliseconds.
  • Number of concurrent threads: when the number of concurrent threads of all inlet traffic on a single machine reaches the threshold, the system protection is triggered.
  • Inlet QPS: when the QPS of all inlet flows on a single machine reaches the threshold, the system protection is triggered.

Keywords: Java Distribution filter sentinel gateway

Added by sargenle on Sat, 05 Mar 2022 08:51:47 +0200