Detailed Explanation of Sentinel Flow Control and Current Limiting Framework

1. Introduction

Sentinel is a high-availability, high-scalability, and high-stability open source flow control and circuit breaker degradation framework, which can realize real-time flow control in a distributed system and prevent the system from crashing and service degradation due to excessive traffic.

Sentinel provides the following features:

  • Flow control: By configuring different rules, limit the request flow.
  • Fuse downgrading: When an abnormal situation occurs in the system, the system can be automatically fusing to ensure the availability of the system.
  • System load protection: During peak system load periods, request traffic can be limited to avoid exhaustion of system resources.
  • Real-time monitoring: It can monitor the system's request traffic, response time, error rate and other indicators in real time.

Sentinel is oriented to all Java applications, and can support applications based on service frameworks such as Spring Cloud, Dubbo, and gRPC, and can also be integrated into applications based on web containers such as Tomcat and Jetty.

2. The principle of Sentinel

The principle of Sentinel to implement flow control and fuse downgrade is to intercept the application, and then judge whether the request is allowed or needs to be downgraded according to the predefined rules.

Sentinel's interceptor will establish a chain of responsibility in the application and intercept requests one by one. During the interception process, Sentinel will count parameters such as Request, Response, and Exception, and perform operations such as fusing or limiting the request according to the statistical information.

There are three main indicators to measure system stability:

  • TPS (Transactions Per Second): The number of transactions processed per second.
  • RT (Response Time): Response time, that is, the time from sending a request to receiving a response.
  • Error Rate: The error rate, that is, the ratio of the number of requests with errors to the total number of requests.

Sentinel evaluates the health status of the application based on these three indicators. When these indicators reach a certain threshold, Sentinel will automatically trigger the corresponding traffic control and circuit breaker downgrade operations.

3. Sentinel Quick Start

Here are a few steps to get started with Sentinel:

  1. First, introduce Sentinel's dependencies in Maven:

     xml 

    copy code

    <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <version>2.2.1.RELEASE</version> </dependency>
  2. Configure Sentinel's startup parameters in Spring Boot:

     properties 

    copy code

    spring.cloud.sentinel.transport.dashboard=http://localhost:8080 spring.cloud.sentinel.transport.port=8719 # Sentinel 控制台连接超时时间(ms) spring.cloud.sentinel.transport.dashboard.request-timeout=5000 # 配置资源的默认规则 spring.cloud.sentinel.rules.defaults[0].grade=QPS spring.cloud.sentinel.rules.defaults[0].count=10

    Among them, spring.cloud.sentinel.transport.dashboardthe address of Sentinel console is configured, and spring.cloud.sentinel.transport.portthe starting port of Sentinel is configured.

  3. Add annotations to methods that require flow control:

     java 

    copy code

    @SentinelResource(value = "demoMethod", blockHandler = "handleBlock") public String demoMethod() { return "Hello World"; } public String handleBlock(BlockException ex) { return "请求被拦截: " + ex.getClass().getSimpleName(); }

    In the above code, we use @SentinelResourceannotations demoMethodto control the flow of the method, and set the fallback method to handleBlock. When the current limit is triggered, handleBlockthe method to return a custom response result.

4. Use Sentinel for fuse downgrade

Sentinel is not only capable of flow control, but also capable of circuit breaker degradation. When a certain degree of abnormality occurs in the system, the fuse downgrade strategy will be triggered to ensure the availability of the system. The following are a few steps for circuit breaker downgrade using Sentinel:

  1. Add @SentinelResourceannotations , and specify fallbackClassand fallbackattribute values:

    java

    copy code

    @SentinelResource(value = "demoMethod", blockHandler = "handleBlock", fallbackClass = DemoServiceFallback.class, fallback = "fallback") public String demoMethod() { return "Hello World"; } public String handleBlock(BlockException ex) { return "请求被拦截: " + ex.getClass().getSimpleName(); }

    In the above code, we specified fallbackClassand fallbackattributes to define the implementation class and method name of the fallback method. When the service is downgraded, the fallback method will be executed to return a custom response result.

  2. Define the fallback method and its implementation class:

    java

    copy code

    public class DemoServiceFallback { public static String fallback() { return "请求被熔断降级"; } }

    In the above code, we defined fallbackthe method and its implementation class DemoServiceFallback. When the service is downgraded, fallbackthe method to return a custom response result.

5. Sentinel's flow control rules and hotspot parameter flow limit

Sentinel supports a variety of flow control rules and hotspot parameter flow limiting strategies, which can be flexibly configured according to business scenarios.

flow control rules

Sentinel's traffic control rules are as follows:

  1. QPS flow control: through QPS control on the API, that is to limit the number of requests that the interface can handle within a certain period of time.

    java

    copy code

    @SentinelResource(value = "demoMethod", blockHandler = "handleBlock") @RateLimiter(10) public String demoMethod() { return "Hello World"; } public String handleBlock(BlockException ex) { return "请求被拦截: " + ex.getClass().getSimpleName(); }

    In the above code, we use @RateLimiterannotations to implement QPS flow control on the interface, and set the flow limit threshold to 10.

  2. Thread number flow control: Avoid thread pool overload by limiting the number of threads in the thread pool.

     java 

    copy code

    @SentinelResource(value = "demoMethod", blockHandler = "handleBlock") @ThreadPool(name = "demoMethod", coreSize = 5, maxQueueSize = 10) public String demoMethod() { return "Hello World"; } public String handleBlock(BlockException ex) { return "请求被拦截: " + ex.getClass().getSimpleName(); }

    In the above code, we use @ThreadPoolannotations control the flow of the thread pool, and set the number of core threads in the thread pool to 5.

Hotspot parameter current limit

Hotspot parameter current limiting is an important feature of Sentinel, which can effectively prevent the entire system from crashing due to malicious use of a certain parameter. For example, assuming that there is a product details interface, the parameter skuId may have hotspots, that is, some specific product skuIds will be requested in large numbers. If traffic is not limited, the system may crash when a malicious attack of a specific skuId occurs.

The following is an example of using Sentinel to implement hotspot parameter current limiting:

 
 

java

copy code

@SentinelResource(value = "demoMethod", blockHandler = "handleBlock") @HotParam(value = "skuId", mode = ParamFlowItem.FlowControlMode.QPS, threshold = 100) public String demoMethod(@RequestParam Long skuId) { return "Hello World"; }

In the above code, we use @HotParamannotations to limit the skuId parameter, and set the limit threshold to 100 QPS. In this way, when a skuId's request exceeds 100 QPS, Sentinel's current limiting mechanism will be triggered. In this way, we can avoid the situation where the entire system crashes due to the abnormal use of a hot parameter.

6. Advantages and disadvantages of Sentinel

As a mature distributed system traffic guard, Sentinel has the following advantages:

  • Rich functions: Sentinel provides a full range of service quality guarantees such as flow control, circuit breaker degradation, system protection, and real-time monitoring.
  • Ease of use: Sentinel provides a friendly web interface for easy configuration and management of rules.
  • Highly customizable: Sentinel provides a variety of SPI extension points, which can be customized and extended according to business needs.
  • Open source and free: Sentinel is completely open source and free to use.

Of course, Sentinel also has the following disadvantages:

  • Does not support language diversity: Sentinel currently only supports Java applications, and is not friendly enough for applications in other programming languages.
  • The documentation is a bit simple: Although Sentinel's documentation is relatively comprehensive, there are still some pitfalls that need attention in some practical scenarios.

Seven, Sentinel advanced features

Both synchronous and asynchronous calls are supported

Sentinel can conveniently support synchronous and asynchronous calls. For synchronous calls, you can use the @SentinelResource annotation to specify the method that needs to be protected in the annotation, and set the corresponding circuit breaker downgrade, flow control rules and other restrictions.

For asynchronous calls, you need to use the asynchronous Entry class provided by Sentinel to implement protection. When using asynchronous Entry for protection, you need to insert Sentinel's interceptor during the asynchronous call, and manually release the corresponding resources after the asynchronous operation is completed, so that Sentinel can count and record the corresponding data.

For example, here's an example of securing with an asynchronous Entry:

 
 

java

copy code

CompletableFuture.supplyAsync(() -> { Entry entry = null; try { entry = SphU.asyncEntry("demoMethod"); // 异步逻辑 return "Hello World"; } catch (BlockException ex) { return "blocked by Sentinel: " + ex.getClass().getSimpleName(); } finally { if (entry != null) { entry.exit(); } } }).thenAccept(result -> System.out.println("result: " + result));

In the above code, we first use the SphU.asyncEntry method to create an asynchronous Entry, and then perform business operations in the asynchronous logic. It should be noted that when the asynchronous operation is completed, it is necessary to manually call the entry.exit() method to release the corresponding resources.

Support multiple current limiting modes

Sentinel supports multiple current limiting modes, and different current limiting algorithms can be selected according to actual needs.

  • Direct mode: Limit resources directly, and trigger flow limit if the threshold is exceeded.
  • Association mode: Limit flow by associating resources. For example, when controlling the flow of an API, flow control can be realized by associating the database connection pool that accesses the API.
  • Link mode: To ensure the stability of the system by controlling the flow of the entire link.

When using association mode and link mode, you need to set related association links and link information in the rules.

For example, here's an example of flow control using the association pattern:

 
 

java

copy code

@SentinelResource(value = "demoMethod", blockHandler = "handleBlock") public void demoMethod(@RequestParam("id") Long id) { System.out.println("request id: " + id); } @Bean public RequestOriginParser requestOriginParser() { return new DemoRequestOriginParser(); } public static class DemoRequestOriginParser implements RequestOriginParser { @Override public String parseOrigin(HttpServletRequest request) { String origin = request.getParameter("origin"); if (StringUtils.isEmpty(origin)) { return "unknown"; } return origin; } } @Configuration public class SentinelConfig { @Autowired private RequestOriginParser requestOriginParser; @PostConstruct public void init() { FlowRuleManager.register2(Arrays.asList( new FlowRule("demoMethod").setCount(5) .setGrade(RuleConstant.FLOW_GRADE_QPS) .setLimitApp("default") .as(FlowRule.class) .setStrategy(RuleConstant.STRATEGY_RELATE) .setRefResource("demoDatabase"))); } @Bean public SentinelResourceAspect sentinelResourceAspect() { return new SentinelResourceAspect(); } @Bean public SentinelServletRequestAspect sentinelServletRequestAspect() { return new SentinelServletRequestAspect(); } }

In the above code, we use the @SentinelResource annotation for flow control, and associate the database connection pool resources through setRefResource and setStrategy, and set the flow-limiting strategy as the association mode.

Support multiple rule matching methods

Sentinel supports multiple rule matching methods, and different rule matching strategies can be selected according to actual needs.

  • Exact match: Exact match is the most commonly used matching method, which can be based on exact match rules such as resource names and current limiting parameters.
  • Substring matching: usually used for fuzzy matching of resource names, such as limiting the flow of all requests of an API.
  • Regular matching: Rule matching can be performed based on regular expressions, providing a higher level of flexibility.

For example, here's an example using a regex matching rule:

 
 

java

copy code

@SentinelResource(value = "demoMethod", blockHandler = "handleBlock") public void demoMethod(@RequestBody Map<String, Object> data) { System.out.println("request data: " + data); } @Configuration public class SentinelConfig { @PostConstruct public void init() { SystemRuleManager.loadRules(Collections.singletonList( new SystemRule() .setHighestSystemLoad(1.0) .setAvgLoad(0.8) .setQps(200)))); ParamFlowRuleManager.loadRules(Collections.singletonList( new ParamFlowRule() .setParamIdx(0) .setGrade(RuleConstant.FLOW_GRADE_QPS) .setCount(5) .setDurationInSec(1) .setParamFlowItemList(Collections.singletonList( new ParamFlowItem().setObject("special_object") .setCount(2))))); DegradeRuleManager.loadRules(Collections.singletonList( new DegradeRule("demoMethod") .setCount(100) .setTimeWindow(10) .setGrade(RuleConstant.DEGRADE_GRADE_RT) .setCount(20) .setMinRequestAmount(10)))); FlowRuleManager.loadRules(Collections.singletonList( new FlowRule() .setGrade(RuleConstant.FLOW_GRADE_QPS) .setResourceRegex("/api/.*") .setCount(10) .setLimitApp("default") .as(FlowRule.class)))); } @Bean public SentinelResourceAspect sentinelResourceAspect() { return new SentinelResourceAspect(); } }

In the above code, we use the setResourceRegex method to set a regular matching rule to control the flow of all resources starting with /api/.

8. Use cases

Gateway current limiting using Sentinel and Spring Cloud Gateway

First, we need to introduce Sentinel and Spring Cloud Gateway dependencies into the project:

 
 

xml

copy code

<!-- 引入 Sentinel --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <!-- 引入 Spring Cloud Gateway --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency>

Then, we can add the related configuration of Sentinel and Spring Cloud Gateway in application.ymlthe file :

 
 

yaml

copy code

spring: cloud: sentinel: transport: dashboard: localhost:8250 server: port: 8080 spring: cloud: gateway: routes: - id: test_route uri: http://httpbin.org predicates: - Path=/anything/**

In the above configuration, we specified the dashboard address of Sentinel and the port number of Spring Cloud Gateway, added a route test_routenamed matching path is /anything/**, and forwarded the route to http://httpbin.org.

Next, we need to add Sentinel rules to Spring Cloud Gateway to control the flow of requests:

 
 

java

copy code

@Bean public SentinelGatewayFilterFactory sentinelGatewayFilterFactory() { return new SentinelGatewayFilterFactory(); } @Bean public GatewayFilterChain gatewayFilterChain(RouteLocator routeLocator, List<GatewayFilterFactory> gatewayFilters) { DefaultGatewayFilterChain chain = new DefaultGatewayFilterChain(routeLocator.getRoutes(), gatewayFilters); chain.add(0, sentinelGatewayFilterFactory.apply(new Object())); return chain; }

In the above code snippet, we created a Bean sentinelGatewayFilterFactorynamed to create Sentinel's gateway filter and add it to Gateway.

Finally, we need to configure rules in the Sentinel dashboard to control request traffic:

  • Open the Sentinel console, in the left navigation bar, select Flowand click 新增.
  • Type in the Resourceinput box /anything/**.
  • Enter the maximum value to limit the request traffic in the 限流阈值input box.
  • click 新增.

Using Sentinel and RocketMQ to implement message flow control

First, we need to introduce Sentinel and RocketMQ dependencies into the project:

 
 

xml

copy code

<!-- 引入 Sentinel --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <!-- 引入 RocketMQ --> <dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-spring-boot-starter</artifactId> <version>2.0.3</version> </dependency>

Then, add the related configuration of Sentinel and RocketMQ in application.ymlthe file :

 
 

yaml

copy code

spring: cloud: sentinel: transport: dashboard: localhost:8250 rocketmq: name-server: localhost:9876 producer: group: my-group

Among them, we specified the dashboard address of Sentinel, the NameServer address of RocketMQ, and the producer group name of RocketMQ.

Next, we need to add Sentinel rules for the producer to control the flow of message sending:

 
 

java

copy code

@Slf4j @Service public class MyProducer { @Autowired private RocketMQTemplate rocketMQTemplate; @PostConstruct public void init() { // 添加 Sentinel 规则 String resourceName = "myTopic:myTag"; String ruleKey = "myRuleKey"; int threshold = 100; DegradeRule rule = new DegradeRule(resourceName, ruleKey, threshold); rule.setGrade(RuleConstant.DEGRADE_GRADE_RT); rule.setTimeWindow(10); List<DegradeRule> rules = new ArrayList<>(); rules.add(rule); DegradeRuleManager.loadRules(rules); } public void sendMessage(String message) { try { rocketMQTemplate.convertAndSend("myTopic", "myTag", message); } catch (Exception e) { log.error("发送消息失败,message: {}", message, e); } } }

In the above code, we have added a Sentinel rule to myTopic:myTagthe resource . The function of this rule is: when the RT (response time) of the resource exceeds 10 milliseconds, a fuse will be triggered, further requests will be rejected, and the message system will not be affected. run. The threshold of the rule is 100, that is, when there are more than 100 messages in one second, the rate limit will be triggered.

Finally, Sentinel rules also need to be added in the consumer to control the flow of message consumption:

 
 

java

copy code

@Slf4j @Service public class MyConsumer { @RocketMQMessageListener(topic = "myTopic", consumerGroup = "my-group") @SentinelResource(value = "myTopic:myTag", blockHandler = "handleBlockedMessage") public void handleMessage(@Payload String message) { log.info("接收到消息:{}", message); } public void handleBlockedMessage(String message, BlockException e) { log.error("消息被拒绝,message: {}", message); } }

In the above code, we added a Sentinel rule to myTopic:myTagthe resource , and specified the processing method when the Sentinel rule limit occurs. During the consumption process, if the threshold value of the Sentinel rule is exceeded, the flow limit will be triggered and further message consumption will be refused.

Guess you like

Origin blog.csdn.net/Trouvailless/article/details/130969200