Spring Cloud Alibaba - Sentinel&OpenFeign

       

Table of contents

A basic use of sentinel

A current limiting rule

Two fuse rules

1 Slow call ratio

2 Abnormal ratio

3 outliers

Other introductions to the three sentinel current limiting rules

1 Hot spot rules

2 Authorization rules

3 System rules 

Two advanced use of sentinel

A custom response message

Two configuration persistence (nacos)

Three OpenFeign use introduction


        Sentinel is a traffic management component, which can perform system protection such as service flow limit, fuse downgrade, etc. For some services with high concurrency and high access, in order to ensure the stability of the system, it is an essential component. Generally, it will be used with components such as gateway and feign. The combination with gateway will be explained in the subsequent articles related to gateway. This article will introduce the use of sentinel and the combination of sentinel and feign.

A basic use of sentinel

        Before introducing the use of sentinel, you need to do the preparation work. Download the sentinel console service and start it. Its console is a jar package, which can be used directly after downloading. The download address is: Releases · alibaba/Sentinel · GitHub , in Download the required version of the jar package, and then start it. The default port of the sentinel console is 8080. After accessing the address, it will enter the login interface. The user name/password is: sentinel/sentinel. After logging in, the following page will appear:

 After the above page appears, the sentinel console is started. It should be noted that when there is no persistent configuration, sentinel belongs to the lazy loading mode. There will be a display of related services and resources. The next step is the integration of sentinel in the spring boot project, and the specific operation and use of sentinel.

        Create a new spring boot project. After adding the basic dependencies, add the following dependencies:

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

Then add the following configuration to the project configuration file:

spring:
  cloud:
    sentinel:
      transport:
        # sentinel控制台地址,
        dashboard: 127.0.0.1:8080
        # 默认使用8719端口,如果端口被占用会以1为长度递增,直到找到未被占用的端口
        port: 8719
      # 针对限流中的链路规则,如果要使用链路限流,则需配置为,值为false,默认为true
      web-context-unify: false

Add a simple controller to the spring boot project with the above configuration, then write an interface, start the project, access the interface address, and you will find the project in the sentinel console.

A current limiting rule

        First of all, let's take a look at current limiting. The purpose of current limiting is to prevent the current service from making a large number of visits in a short period of time, exceeding the carrying capacity of the service and causing the service to crash.

        After completing the above preparatory work, let's find the following location, that is, the location of the current limiting rule configuration:

 When we click flow control, the following pop-up box will appear:

         Resource name : In the case of no special processing, it is our access path, and you can also use the @SentinelResource(value="xxx") annotation for custom naming;

        For the source : the default is default, and generally will not be modified;

        Threshold type : qps (interface access data per second) and the number of concurrent threads, that is, the current limiting type;

        Standalone Threshold : Configure threshold types to be used in combination. For example, select qps for the threshold type and configure 10 for the threshold of a single machine. This means that when the qps of a single machine exceeds 10, the current limiting rule is triggered.

        When no advanced option configuration is performed, the default current limiting policy is to directly reject. We can first configure it as 1 to see the current limiting effect, and then access the interface continuously to trigger the current limiting, and the following return information will appear, which is sentinel’s default return information, and we will introduce sentinel’s custom return later.

 After understanding the basic current limiting configuration, let's take a look at the advanced options:

Flow control mode is divided into:

        Direct : When the accessed address reaches the current limit rule, the current limit rule is directly triggered;

        Association : When the association is selected, an input box for associated resources will appear. Assume that there are two interfaces, /testA and testB, which are configured as associations in the flow control rule of the resource named /testA, and the associated resource is /testB. When /testB reaches the configured flow control limit, /testA will be blocked. Limiting. It should be noted that there is no need to configure the rules for /testB separately. The current basic flow control rules are for /testB.

        

        Link : When selecting a link, an input box for the entry resource will appear. If it is a higher version of sentinel, there is no need to configure web-context-unify: false, it should be around version 2.2.5.RELEASE. When using a link, it is used with the @SentinelResource annotation. For example, both interfaces /testA and testB now access the method base(). We add the @SentinelResource("base") annotation to the base() method to access / After testA (/testB), the base link will appear in the cluster point link. When using the link, we configure it on the base instead of the interface location. For example, the current entry resource configuration is /testA, then the /testB interface will not limit the current even if the current limiting rule is met.

Flow control effect , it should be noted that the flow control effect will only appear when the threshold type is qps. If the threshold type is the number of concurrent threads, the flow control effect defaults to fast failure, that is, the flow control effect is set for qps of:

        Fail fast : fail directly without any processing;

        wam up (preheating) : When wam up is selected, an input box for the duration of the preheating will appear. The specified preheating is the execution time, and the qps recharge start value of the service is increased to the set value. The calculation formula for the start value is: stand-alone Threshold/codeFactor, the default value of codeFactor is 3. For example, the current stand-alone threshold configuration is 20, and the warm-up time is 6s. That is, the stand-alone threshold is 7 at the beginning, and the stand-alone threshold rises to 20 after 6s.

Regarding the warm-up effect of this setting, you can view it through the real-time monitoring of the sentinel console after setting the flow control rules and performing related operations.

         Waiting in line : When you choose to wait in line, the output box of the timeout time will appear. Queuing refers to allowing requests to pass through evenly, rather than one-off requests. For example, if the configured qps is 2, it means that a request is passed every 500ms (it should be noted that queuing and waiting currently does not support the situation of qps>1000). So what does the timeout period represent? This involves a calculation problem. For example, the timeout configuration is 10000ms, and the value of qps configuration is still 2, that is, the interval time is still 500ms. If a request comes in at this time, it is found that there are still 5 requests in front of it and then queued. It is the first Six requests need to wait for 3000ms before it will be executed, but if 3000ms<10000ms, then it will wait in line; but if there are 30 requests in front of the queue, it needs to wait for 15500ms, at this time 15500ms>10000ms, then it will The current limiting rule is triggered and rejected.

        The above is an introduction to the current limiting rules, and you can simulate according to each situation. Concurrent threads can be simulated by jemeter. The association or link can be simulated by postman's automatic request method, and examples are not written and simulated for each case here. 

Two fuse rules

        The fuse is actually to prevent the avalanche of services from being dangerous. The current services are basically deployed in the form of microservices, which means that there will be calls between services. If there is no fuse limit, when the service calls between services, the called When the service fails and does not respond for a long time, the IO resource has been occupied and cannot be released. When there are too many such requests, there is no problem for the service caller, but due to the reason of the called service, the entire service unavailable. In order to prevent this kind of danger, we can use sentinel's circuit breaker rules to deal with it.

        The configuration location of the fuse rule:

 There are three types of circuit breaker rules, the proportion of slow calls, the proportion of abnormalities, and the number of abnormalities. The following will introduce these three circuit breaker rules. Before the introduction, there is another knowledge point to understand, that is, the three states of sentinel fuse:

        OPEN : Fuse open state, reject all requests;

        HALF_OPEN : To detect the recovery status, if the next request can be accessed normally and does not trigger the fuse rule, then end the fuse, otherwise continue to fuse;

        CLOSE : The fuse is closed, and the request is processed normally.

After introducing the above three states, let's look at the three strategies of fusing.

slow call ratio

        After clicking the fuse rule of the slow call ratio, the following related input information will appear:

         Resource name : That is to add the circuit breaking rule request path, or it can be customized through the @SentinelResource annotation.

        Circuit breaker strategy : There are three types of circuit breaker strategies, slow call ratio, abnormal ratio, and abnormal number;

        Maximum RT : The maximum response time allowed by the call, that is, when the actual request consumption time is greater than this time, this call will be classified as a slow call;

        Ratio threshold : here refers to the allowed ratio of slow calls, and the value range is 0-1. For example, if the value is set to 0.1, the ratio of slow calls cannot exceed one-tenth;

        Fuse duration : When the fusing rule is triggered, the service is in the service rejection within the specified time, which is the OPEN state mentioned above;

        Minimum number of requests : Only when the number of requests is greater than this value will the verification of the fuse rule be triggered. If it is less than this value, the verification of the circuit breaker will not be performed;

        Statistical duration : Statistical request data within the specified time range.

        The above is an introduction to each field of the circuit breaker rule. For different circuit breaker strategies, most parameters have the same meaning, and only some parameters are uniquely owned by the circuit breaker strategy. For the slow call ratio, the maximum RT and the ratio threshold are configuration items used to configure slow call information.

        Let's use a set of specific configurations to illustrate what it means. The maximum RT is 500, the ratio threshold is 0.4, the fuse time is 1, the minimum number of requests is 5, and the statistics time is 1000. It means to count requests within 1s In this case, if the number of requests within 1s is less than 5, the fuse state is in CLOSE; if the number of requests is greater than 5, for example, there are 10 requests, then count the number of requests whose response time is greater than 0.5s among these 10 requests, and if the number of requests greater than 0.5s If the number of requests is less than 4 (0.4*10), then the fusing state is CLOSE, otherwise it is OPEN state, and the OPEN state will last for 1s. When the fusing time reaches 1s, the fusing state is HALF_OPEN state. If the next request, the response time is less than 0.5s, the fuse state returns to the CLOSE state, otherwise continue to repeat the above state change, that is, the fuse is in the OPEN state for 1s, and then changes to the HALF_OPEN state.

        When simulating this situation, you can use the sleep method to simulate, and simulate slow response through thread sleep.

2 Abnormal ratio

        Abnormal ratio : the ratio of abnormal requests to the total requests.

        Or take a specific example to illustrate, the proportion threshold is 0.4, the fuse duration is 1, the minimum number of requests is 5, and the statistics duration is 1000, which means that the statistics of requests within 1s, if the number of requests within 1s is less than 5 , the fuse state is CLOSE; if the number of requests is greater than 5, for example, there are 10 requests, then count the number of abnormal requests among the 10 requests, and if the number of abnormal requests is less than 4 (0.4*10), then the fuse state is CLOSE, otherwise it is in the OPEN state, and the OPEN state will last for 1s. When the fusing time reaches 1s, the fusing state will be in the HALF_OPEN state. If the response time of the next request is less than 0.5s, the fusing state will return to the CLOSE state, otherwise continue to repeat The above state changes, that is, the fuse is in the OPEN state for 1s, and then changes to the HALF_OPEN state.

outliers

         Exceptions : The number of requests with exceptions.

        Or take a specific example to illustrate, the number of exceptions is: 4, the fuse duration is 1, the minimum number of requests is 5, and the statistics duration is 1000. It means that the statistics of requests within 1s, if the number of requests within 1s is less than 5, the fuse state is CLOSE; if the number of requests is greater than 5, for example, there are 10 requests, then count the number of abnormal requests among the 10 requests, if the number of abnormal requests is less than 4, then the fuse state is CLOSE, otherwise it is OPEN state, the OPEN state will last for 1s. When the fusing time reaches 1s, the fusing state is HALF_OPEN state. If the response time of the next request is less than 0.5s, the fusing state will return to the CLOSE state, otherwise continue to repeat the above state change , that is, the fuse is in the OPEN state for 1s, and then changes to the HALF_OPEN state.

Other introductions to the three sentinel current limiting rules

hotspot rule

        In the current limiting rules we introduced in the first part, we only implement the overall current limiting rules for the requested resources. If we want to limit the current in a more fine-grained manner, we need to use hotspot rules. For example, we want to limit the number of purchases of a specified hot-selling product within a certain period of time. The hotspot rule refers to a request path, the request parameter contains the entry flow limiting rule of the hotspot data, and the request that does not include the hotspot data does not enter the hotspot data. Make an explanation through the following figure:

 Next, let's take a look at how to configure:

 

         Resource name : request path address;

        Current limiting mode : currently only supports qps and cannot be modified;

        Parameter index : refers to the parameter index in the interface, the index starts from 0;

        There is also a set of parameters in the parameter exceptions:

        Parameter type : Currently, 8 parameter types are supported: byte, short, int, long, float, double, String;

        Parameter value : set hotspot data;

        Current limit threshold : the current limit qps value of this hotspot data.

        The above is an introduction to the configuration of hotspot rules. Interested students can try it out by themselves.

2 Authorization rules

        Authorization rules refer to which resources are allowed to be accessed by the current resource and which resources are not allowed to be accessed. It is a black and white list mechanism, and its configuration entry is as follows:

 

3 System rules 

        The rules we introduced above are actually fine-grained current restrictions, which can be considered as API-level current restrictions, but system rules are coarse-grained restrictions, which are for the entire service. Its configuration entry is as follows:

 

LOAD : Use the average load of the system for 1 minute as a heuristic indicator for adaptive system protection. System protection will be triggered when the 1-minute average load of the system exceeds the set threshold, and the current number of concurrent threads of the system exceeds the estimated system capacity, which is estimated by system capacity = maxQps (maximum qps) * minRt (minimum response time) . Setting reference value: cup cores (cpu core number)* 2.5.

RT : response time

The number of threads, entry qps and cpu utilization are literally

Two advanced use of sentinel

A custom response message

        When we use sentinel for current limiting or fusing, if we do not configure it, the default limit information of sentinel will be used. For example, the displayed information is: Blocked by Sentinel (flow limiting). This display method is suitable for customers in production environments. It is very unfriendly, we can use the @SentinelResouce annotation to return custom data.

        Let's take the following simple code as an example to illustrate:

        Create a new exception handling class, which contains two methods, one is the prompt when the current limiting rule is triggered, and the other is the prompt when an exception occurs:

// 自定义异常处理类
public class SelfSentinelHandler {
    // 当资源触发限流或者熔断规则的时候,返回的错误提示信息
    public static String limite(BlockException e){
        return "sentinel limite";
    }
    
    // 当调用资源发生异常时,返回的错误提示信息
    public static String systemError(BlockException e){
        return "system error";
    }
}

        After the development of the above custom error message class is completed, the next step is to call the configuration at the resource:

@GetMapping("/test")
@SentinelResource(blockHandlerClass = SelfSentinelHandler.class, blockHandler = "limite"
    , fallbackClass = SelfSentinelHandler.class, fallback = "systemError"
    , exceptionsToIgnore = {IOException.class, InterruptedException.class})
public String test(){
    return "hello sentinelC";
}

Here we use the @SentinelResource annotation, and the following explanations are given for each attribute in the annotation:

        blockHandlerClass : The class that handles the prompt information when the current limit or fuse rule is triggered;

        blockHandler : The method called when the current limit or circuit breaker rule is triggered;

        fallbackClass : The class that handles the prompt information when an exception occurs in the call interface;

        fallback : the method to call when an exception occurs in the calling interface;

        exceptionsToIgnore : When an exception occurs in the call interface, ignore the exception information, and these exceptions can be returned directly.

        It should be noted that because we define related exception handling methods in other classes, we need to use static to modify these methods; of course, if you do not configure blockHandlerClass, fallbackClass, and only configure blockHandler and fallback, these methods are developed at the same time as the current interface In a class, there is no need to use static for decoration.

Two configuration persistence (nacos)

        Sentinel uses lazy loading. The corresponding link information will only appear after the corresponding API is accessed, and then set its current-limiting fuse rules. When the project is restarted, the current-limiting fuse rules we configured will disappear. Obviously, in In the production environment, this configuration method is inappropriate, which involves the persistence of the configuration of the current limiting and circuit breaker rules. Here we cooperate with nacos for persistence.

        Before introducing the configuration of persistence through nacos, let's have an overall understanding of persistence. There are currently two modes of persistence supported by sentinel:

        1. Pull mode, that is, the client actively pulls the flow control rules through a scheduled task. This method has a fatal shortcoming, that is, when the flow control rules change, the client obtains the flow control rules by a delay of. Using this method of configuration, there are currently eurake, dynamic data sources, etc.;

        2. In the push mode, the client monitors changes in flow control rules in real time by registering and listening to events. Currently, the data sources of the push mode supported by sentinel include: zookeeper, apollo, nacos, redis, etc.

        This article introduces the use of nacos. If you want to know other modes, you can refer to the official document of sential: Persistence of flow control rules .

Let's first look at the principle of persistent flow control rules (for nacos):

         Under normal circumstances, the nacos and sentinel consoles should interact with each other, that is, modify the flow control rules in the nacos console, and the flow control rules of the sentinel console will be modified synchronously, which is currently implemented; the sentinal console Modifying the flow control rules should also be modified in nacos synchronously, but this is currently not implemented. You must pay attention when using it. If you want to permanently modify the flow control rules, you must modify them in nacos.

First, we need to introduce dependencies:

        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
            <version>1.8.1</version>
        </dependency>

Then in the configuration file, add the following configuration:

spring:
  cloud:
    nacos:
      discovery:
        server-addr: 172.30.10.103:8848
    sentinel:
      web-context-unify: false
        # sentinel控制台的访问信息
      transport:
        dashboard: 172.30.10.103:8080
        port: 8719
      # sentinel持久化的相关配置
      datasource:
        nacos:
          nacos:
            # nacos服务端地址
            serverAddr: 172.30.10.103:8848
            # naocs命名空间
            namespace: 4b57e563-2039-42f4-86b1-9c4c7cf58bfc
            # nacos组信息
            groupId: DEFAULT_GROUP
            # 在nacos中存放持久化配置的文件名称
            dataId: sentinel-config.json
            # 持久化的流控规则类型,目前支持flow,degrade,param-flow,system,authority,gw-flow,gw-api-group这几种,他们具体代表什么,我们后续再源码章节会进行介绍
            ruleType: flow

After completing the above configuration, the next step is to go to the specified location of nacos and configure the persistent file

 Because the ruleType we configured in the project is flow, then our configuration information here is:

[
    {
        "resource": "/sentinel/config/demo",
        "limitType": "default",
        "grade": "1",
        "count": "1",
        "strategy": "0",
        "controlBehavior": "0",
        "clusterMode": false
    }
]

resource: resource name, corresponding to the access address of the api (the name specified by the @SentinelResource annotation);

limitType: source application, default is default;

grade: threshold type, 0-number of threads, 1-qps;

count: stand-alone threshold;

strategy: flow control mode, 0-direct, 1-association, 2-link;

controlBehavior: flow control effect, 0-fail fast, 1-warm up, 2-queue waiting;

clusterMode: whether to cluster, true/false

        It should be noted that if the ruleType in the configuration file is different, then the fields in the nacos configuration file are different, and configure according to the actual situation.

        After we complete the above configuration, start our spring boot service and access the corresponding api. At this time, we will find that in the sentinel console, there are our corresponding flow control rule configurations.

Three OpenFeign use introduction

        Why introduce OpenFeign here? One reason is that as a service call component, OpenFeign is relatively simple and does not need to be introduced in a separate article; another reason is that, as we said when we introduced the fuse mechanism, it is mainly aimed at calls between services . In the microservice architecture, one of the commonly used calls between services is OpenFeign. It should be noted that the use of OpenFeign must be used with the registration center, which is a component in the spring cloud. The registry component we use here is nacos.

        The underlying layer of OpenFeign uses HttpClient for service calls, and we know from the previous article that nacos itself has inherited the ribbon for load balancing, and no additional configuration is required for cluster calls here. Next, let's introduce the use of OpenFeign. If you want to use OpenFeign, there must be both service providers and service consumers. For service providers, we don't need to do special processing, just create a basic spring boot project, and then register it in nacos. This article introduces the use of sentinel, then add related configuration of sentinel to configure fuse rule. Next, let's introduce the processing of the service consumer. It is necessary to add nacos as the relevant dependency of the registration center, based on nacos as the configuration center.

        First of all, add the relevant dependencies of OpenFeign:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

        Secondly, add annotations to start OpenFeign in the startup class, or add a bean object that prints OpenFeign logs in the startup type:

@SpringBootApplication
@EnableDiscoveryClient
// 使用openFeign,如果不添加该注解,无法使用
@EnableFeignClients
public class FeignConsumer9003Application {

    public static void main(String[] args) {
        SpringApplication.run(FeignConsumer9003Application.class, args);
    }
    
    // 打印openFeign的注解
    @Bean
    Logger.Level feignLoggerLevel(){
        //开启详细日志,这里的日志级别有四种,默认为NONE-不打印任何日志
        // BASIC:记录请求方法,URL,响应状态码以及执行时间
        // HEADERS:除了BASIC中定义的信息之外,还有请求和响应的头信息
        // FULL:除了HEADERS级别的信息以外,还有请求和响应的正文以及元数据
        return Logger.Level.FULL;
    }
}

        Then, add relevant configurations in the configuration file, the configuration of nacos is necessary, the configuration of OpenFeign is not necessary, it is a special setting for some parameters

// 因为openFeign在调用时通过ribbon作为负载均衡,因此OpenFeign的超时时间也就是ribbon的超时时间
ribbon:
  # 指的是建立连接后从服务器读取到可用资源所用的时间
  ReadTimeout: 5000
  #指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
  ConnectTimeout: 5000
// openFeign的日志打印级别以及对应的类型信息
logging:
  level:
    org.springframework.stereotype.Service.OpenfeignService: debug

        Finally, it is the writing of the code. First, you need to write an interface, and the service consumer calls the service consumer by calling the relevant methods of this interface.

@Service
// 该注解为OpenFeign的相关注解,注解里面的值为服务提供者注册到nacos中的服务名
@FeignClient("provider-service")
public interface OpenfeignService {
    // 服务提供者提供的请求地址以及请求方式
    @GetMapping("/provider/product/{id}")
    // 方法签名,方法入参以及返回值一定要与服务提供者中对应接口完全一致
    String getProduct(@PathVariable("id") Integer id);
}

Next, it can be called through bean injection. In the service consumer, the remote call is realized through the call of the local method, and then the service provider and the service consumer are started, and then the relevant interface in the service consumer is accessed. Call the service provider. At this time, the corresponding service will appear in the sentinel console, and we can configure the corresponding circuit breaker rules.

Guess you like

Origin blog.csdn.net/weixin_38612401/article/details/125906939