Service degradation: Sentinel

Posted by fahrvergnuugen on Sat, 15 Jan 2022 06:39:07 +0100

0.1 concept

A powerful flow control component can realize the reliability, elasticity and monitoring of microservices.

Sentinel takes "flow" as the starting point and works in many fields such as flow control, flow shaping, circuit interruption and system adaptive protection to ensure the reliability and elasticity of microservices.

Sentinel has the following functions:

Rich applicable scenarios

Real time monitoring

Extensive open source ecosystem

Multilingual support

Official website: https://github.com/alibaba/Sentinel

Download: https://github.com/alibaba/Sentinel/releases

How to play: Service avalanche, service degradation, service fuse, service current limit

0.2 installation

sentinel is divided into two parts:

Core library: it does not depend on any framework / library and can run in all java runtime environments. At the same time, it also has good support for frameworks such as Dubbo/Spring Cloud.

Dashboard: developed based on springboot, it can be run directly after packaging without additional application containers such as Tomcat.

Installation steps:

Download sentinel-dashboard-1.7.0 this time Jar this version

Run the command to the sentinel Directory: Java - jar sentinel-dashboard-1.7.0 jar

Access sentinel management interface: http://localhost:8080/#/login The account and password are sentinel

Preliminary use of 0.3 Sentinel

(1) start the Nacos registry first

(2) create Maven project as service provider (cloudalibab sentinel service8401)

(3) add Nacos and Sentinel dependencies

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

         (4)application.yml

server:
  port: 8401
spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #nacos service registry address
    sentinel:
      transport:
        dashboard: localhost:8080 #Configure the sentinel dashboard address so that the 8080 monitors 8401
        port: 8719  #The default is 8719. If it is occupied, it will automatically start + 1 scanning from 8719. Until an unoccupied port is found
management: #Endpoint for exposure monitoring
  endpoints:
    web:
      exposure:
        include: '*'

        (5)Controller

@RestController
public class FlowLimitController
{
    @GetMapping("/testA")
    public String testA() throws InterruptedException {
        return "------testA";
    }

    @GetMapping("/testB")
    public String testB() {
        return "------testB";
    }
}

(5) Add @ EnableDiscoveryClient to the startup class

(6) test:

Start sentinel console, start 8401, view sentinel console

Once opened, it is empty because Sentinel uses lazy loading instructions. You can access the Controller once.

0.4 flow control rules

 

Flow control mode

                1. Direct (default): fast failure message default error: Blocked by Sentinel(flow limiting)

 

Question: should we have our own follow-up processing for directly calling the default error message? A fallback like method?

                2. Association: when the resource B associated with A reaches the threshold, the current A is limited

                3. Link: multiple requests call the same microservice

Flow control effect

                1. Quick failure (default)

                2. Warm up

Application scenarios such as: when the seckill system is turned on, there will be a lot of traffic, which is likely to kill the system. The preheating method is to protect the system, slowly put the traffic in, and slowly restore the threshold to the original threshold

                3. Queue up

 

0.5 degradation rules

Sentinel will restrict the call of a resource when it is in an unstable state in the call link (for example, the call timeout or the abnormal proportion increases), so as to make the request fail quickly and avoid affecting other resources and causing cascading errors.

When a resource is downgraded, calls to the resource will be automatically fused within the next downgrade time window (the default behavior is to throw DegradeException).

Sentinel's circuit breaker is not in the half open state: in the half open state, the system will automatically detect whether there is any abnormality. If there is no abnormality, close the circuit breaker and resume use. If there is any abnormality, continue to open the circuit breaker and it is unavailable.

Degradation strategy

                1.RT: when 5 or more requests are continuously entered within 1 second, the average response time (seconds) exceeds the threshold (ms). Within the next time window (s), the call to this method will automatically fuse (throw DegradeException)

The RT upper limit of Sentinel's default statistics is 4900s. If it exceeds this threshold, it will be counted as 4900s. To change the configuration: DCSP sentinel. statistic. max.rt=xxx

                2. Exception ratio: when the access request is > = 5 within 1 second and the exception ratio exceeds the threshold, the resource enters the degraded state. If the condition of request > 5 within 1 second is not met, an error will still be reported as usual

                3. Abnormal constant: when the number of exceptions in one minute of the resource exceeds the threshold, it will fuse. Since the statistics window is at the minute level, if it is less than 60 seconds, it may end the fusing state and enter the fusing state again. Therefore, the time window must be greater than or equal to 60 seconds

0.6 hotspot rules

Use @ SentinelResource(value = "resource name to configure hotspot rules on sentinel")

Note: @ SentinelResource handles the violation of console configuration. If there is an error in operation, go to the exception if you need to go to the exception

@GetMapping("/testHotKey")
@SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey") //If the hot key rule is violated, find a method to find out the details. If the blockHandler is not configured, an exception will be reported
public String testHotKey(@RequestParam(value = "p1",required = false) String p1,
                         @RequestParam(value = "p2",required = false) String p2) {
    //int age = 10/0;
    return "------testHotKey";
}

//Bottom covering method
public String deal_testHotKey (String p1, String p2, BlockException exception){
    return "------deal_testHotKey,o(╥﹏╥)o"; //The default prompt for sentinel is: Blocked by Sentinel(flow limiting)
}

According to the configured current limiting threshold and mode, limit the current of resource calls containing this parameter

This configuration rule: when the first parameter is included (the index starts from 0, that is, p1), the flow is limited once the requested access exceeds 1 second.

Parameter exceptions

The above case demonstrates the first parameter p1. When the QPS exceeds 1 second, the current is limited immediately

Special case: we expect that when p1 parameter is a special value, its current limit is different from the average. If p1 is equal to 5, its threshold can reach 200

0.7 system rules

Control the application inlet flow from the overall dimension, so that the system can run at the maximum throughput and ensure the overall stability of the system.

0.8@SentinelResource

After the service is closed, the temporary flow rule disappears

@SentinelResource(value = "byResource", blockHandler = "handleException")

Limit the flow according to the url address: limit the flow through the accessed url, and the default flow limit processing information of sentinel will be returned

@GetMapping("/rateLimit/byUrl") //Use / rateLimit/byUrl as the resource name and configure it on the console. Do not use the following byUrl
@SentinelResource(value = "byUrl")

Problems faced by the above scheme:

By default, the system does not reflect our own business requirements

Custom processing methods are coupled with business code, which is not intuitive

Each business code is added with a bottom-up, which aggravates the code inflation

The global unified processing method is not reflected

Custom current limiting processing logic:

(1) create a CustomerBlockHandler class to customize the current limiting processing logic

public class CustomerBlockHandler {
    public static CommonResult handleException1(BlockException exception) {
        return new CommonResult(4444, "Custom current limiting processing information....handleException---1");
    }
    public static CommonResult handleException2(BlockException exception) {
        return new CommonResult(4444, "Custom current limiting processing information....handleException---2");
    }
}

(2)Controller usage

//Custom current limiting processing logic
@GetMapping("/rateLimit/customerBlockHandler")
@SentinelResource(value = "customerBlockHandler",
        blockHandlerClass = CustomerBlockHandler.class, //Custom current limiting processing class
        blockHandler = "handlerException2") //Which method in the custom current limiting processing class will tell you the truth

0.9 service fusing

Sentinel integration ribbon+openFeign+fallback

        Ribbon

(1) create Maven project as service provider (cloudalibaba provider payment9003 / 9004)

                (2)application.yml

server:
  port: 9003 //Remember to modify different ports
spring:
  application:
    name: nacos-payment-provider
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #Configure Nacos registry address
management:
  endpoints:
    web:
      exposure:
        include: '*'

(3) add @ EnableDiscoveryClient to the startup class

(4) create Maven project to serve consumers (cloudalibaba consumer Nacos order84)

                (5)application.yml

server:
  port: 84
spring:
  application:
    name: nacos-order-consumer
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #Service registry
    sentinel:
      transport:
        dashboard: localhost:8080 #sentinel console address to enable 8080 monitoring 84
        port: 8719
service-url:
  nacos-user-service: http://nacos payment provider # go to the nacos registry to access the nacos payment provider micro service

(6) add @ EnableFeignClients and @ EnableDiscoveryClient to the startup class

                (7)Controller

@RequestMapping("/consumer/fallback/{id}")
//@SentinelResource(value = "fallback") / / not configured
//@SentinelResource(value = "fallback",fallback = "handlerFallback") //fallback is only responsible for business exceptions
//@SentinelResource(value = "fallback",blockHandler = "blockHandler") //blockHandler is only responsible for sentinel console configuration violations
@SentinelResource(value = "fallback",fallback = "handlerFallback",blockHandler = "blockHandler",
        exceptionsToIgnore = {IllegalArgumentException.class}) //exceptionsToIgnore is an exception that is ignored. If this exception is reported, it will not be revealed 
public CommonResult<Payment> fallback(@PathVariable Long id) {
    CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/"+id, CommonResult.class,id);
    if (id == 4) {
        throw new IllegalArgumentException ("IllegalArgumentException,Illegal parameter exception....");
    }else if (result.getData() == null) {
        throw new NullPointerException ("NullPointerException,Should ID No corresponding record,Null pointer exception");
    }
    return result;
}

//fallback
public CommonResult handlerFallback(@PathVariable  Long id,Throwable e) {
    Payment payment = new Payment(id,"null");
    return new CommonResult<>(444,"Fundus abnormality handlerFallback,exception content  "+e.getMessage(),payment);
}

//blockHandler
public CommonResult blockHandler(@PathVariable  Long id, BlockException blockException) {
    Payment payment = new Payment(id,"null");
    return new CommonResult<>(445,"blockHandler-sentinel Current limiting,No such flow: blockException  "+blockException.getMessage(),payment);
}

(8) test: the @ SentinelResource is not configured and the user is given the error page

Both fallback and blockhandler are configured, and blockhandler is the largest.

        openFeign

(1)openfeign is only related to the consumer side, modified 84

(2) if openFeign depends on

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

(3) activate Sentinel's support for openFeign in yml

feign:
  sentinel:
    enabled: true

(3) test 84 calls 9003. At this time, 9003 is deliberately closed, and the 84 terminal is automatically degraded, which will not be consumed

Topics: Spring Cloud