In the previous study of Spring Cloud Gateway, we have used Sentinel for current limiting, but we have not learned Sentinel in detail, so we need to supplement this knowledge today.
Don't say much, start today's study.
Sentinel introduction
Sentinel It is a lightweight and highly available flow control component open source by Alibaba middleware team and oriented to distributed service architecture. It mainly takes flow as the starting point to help users protect the stability of services from multiple dimensions such as flow control, fuse degradation and system load protection.
1. Basic concepts of sentinel
- resources
Resource is a key concept of Sentinel. It can be anything in a Java application, for example, a service provided by an application, or a service provided by other applications called by an application, or even a piece of code.
As long as the code defined through Sentinel API is a resource, it can be protected by Sentinel. In most cases, you can use method signatures, URL s, or even service names as resource names to identify resources.
- rule
The rules set around the real-time state of resources can include flow control rules, fuse degradation rules and system protection rules. All rules can be adjusted dynamically and in real time.
2. Sentinel features
Sentinel has the following characteristics:
-
Rich application scenarios: Sentinel has undertaken the core scenarios of Alibaba's double 11 traffic promotion in recent ten years, such as spike (i.e. sudden traffic control within the range of system capacity), message peak cutting and valley filling, cluster traffic control, real-time fuse, downstream unavailable applications, etc
-
Perfect real-time monitoring: Sentinel colleagues provide real-time monitoring function. You can see the second level data of a single machine connected to the application on the console, and even the summary operation of clusters with a scale of less than 500
-
Extensive open source Ecology: Sentinel provides out of the box integration modules with other frameworks / libraries, such as spring cloud, Dubbo and grpc. You only need to introduce the dependency of response and make simple configuration to quickly access Sentinel
-
Perfect SPI extension point: Sentinel provides an easy-to-use and perfect SPI extension interface, which can quickly customize logic through the implementation of the extension interface, such as custom rule management, adapting dynamic data sources, etc
3. Sentinel VS Hystrix
Sentinel and previously commonly used fuse degradation Libraries Hystrix What's the difference?
Deficiencies of Hystrix:
- The monitoring platform needs to be built manually
- No set of web interface can give us more fine-grained configuration, flow control, rate control, fusing, degradation, etc
- The thread pool isolation commonly used by Hystrix will cause a large overhead of thread up and down switching.
Hystrix focuses on the fault-tolerant mechanism based on isolation and fusing. Calls that timeout or are blown will fail quickly, and can provide fallback mechanism.
Sentinel focuses on:
- Diversified flow control
- Fuse degradation
- System load protection
- Real time monitoring and console
Project integration
Sentinel can be simply divided into sentinel core library and Dashboard console. The core library does not rely on Dashboard, but it can achieve the best effect in combination with Dashboard.
- Core library (Java client): it does not rely on any framework / library and can run in the runtime environment of Java 8 and above. At the same time, it also has good support for Dubbo / Spring Cloud and other frameworks.
- Dashboard: dashboard is mainly responsible for managing push rules, monitoring and managing machine information.
It is said that resources are the key concept of sentinel. Sentinel is used for resource protection, which is mainly divided into these steps:
- Define resources
- Define rules
- Is the inspection rule effective
After reading so many concepts above, I feel like my head is going bald. Let's try it in practice.
1. Download and start
We can start from https://github.com/alibaba/Sentinel/releases Download sentinel dashboard - $version Jar package.
We can start the downloaded jar package with the following command:
java -Dserver.port=8718 -jar sentinel-dashboard-1.8.3.jar
Where - dserver Port = 8718 specifies the console port
Successfully launched browser access address http://localhost:8718 , default user name and password: sentinel/sentinel
After logging in, it's empty. Next, we'll see how to use it.
2. How to integrate
1. Add dependency
<!-- springcloud alibaba sentinel --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <!-- SpringBoot Web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
2. Add Sentinel configuration
server: port: 9201 spring: application: # apply name name: cloud-sentinel cloud: sentinel: transport: # Console address dashboard: 127.0.0.1:8718
3. Test interface
@RestController public class TestController { @GetMapping("/testA") public Object testA(){ return "testA......"; } @GetMapping("/testB") public Object testB(){ return "testB......"; } }
4. Start the project and access the console
Visit Sentinel console and find it is still empty. What's the matter?
Originally, Sentinel console has lazy loading mechanism. We need to access the interface of our service once before relevant information appears on the console
Let's access the interface localhost:9201/testA
Refresh the Sentinel console again and find that a lot of request related information appears
We can also configure in the configuration file spring.cloud.sentinel.eager: true Property to cancel console lazy loading
In this step, the project has only successfully integrated Sentinel and opened the console. The relevant operations on the console will not be discussed in this article for the time being, and we will start to learn in the next article.
Use case
As mentioned above, using Sentinel for resource protection is mainly divided into these steps:
- Define resources
- Define rules
- Is the inspection rule effective
1. Define resources
Sentinel defines resources in several ways, including throwing exceptions, returning Boolean values, annotation, etc. we won't explain them one by one. For details, please refer to the official documents basic-api-resource-rule (sentinelguard.io)
Here we use annotation to define resources. Sentinel provides @ SentinelResource annotation to define resources and AspectJ extension to automatically define resources and handle blockexceptions.
Because we are through Spring Cloud Alibaba If Sentinel is accessed, the @ SentinelResource annotation can be used without additional configuration. Otherwise, the following dependencies need to be introduced:
<dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-annotation-aspectj</artifactId> <version>x.y.z</version> </dependency>
Let's take a look at the use cases of annotations
@Service public class IUserServiceImpl implements IUserService { public static final String RESOURCE_NAME = "selectUserByName"; @Override @SentinelResource(value = RESOURCE_NAME, blockHandler = "selectUserByNameBlockHandler", fallback = "selectUserByNameFallback") public String selectUserByName(String username) { return "{"userName": " + username + ", "age": 25}"; } // Pay attention to the details of service flow control processing. It must be consistent with the return value and formal parameter of the original function, and the formal parameter must be added with a BlockException parameter at the end, otherwise an error will be reported. FlowException: null public String selectUserByNameBlockHandler(String username, BlockException ex) { System.out.println("selectUserByNameBlockHandler Exception information:" + ex.getMessage()); return "{"code":"500","msg": "" + username + "Service flow control processing"}"; } // When the service is degraded, the function signature is consistent with the original function or a Throwable parameter is added public String selectUserByNameFallback(String username, Throwable throwable) { System.out.println("selectUserByNameFallback Exception information:" + throwable.getMessage()); return "{"code":"500","msg": "" + username + "Service degradation treatment"}"; } }
@SentinelResource annotation contains the following attributes:
parameter | describe |
---|---|
value | Resource name, required item (cannot be empty) |
entryType | Resource call direction, optional (EntryType.OUT by default) |
resourceType | Classification of resources |
blockHandler | The name of the function that handles BlockException |
blockHandlerClass | To process the Class object of a Class, the function must be a static function |
fallback | The fallback logic is used to deal with the exception thrown |
defaultFallback | Used as the default fallback method |
fallbackClass | Class object of exception class. The function must be static |
exceptionsToTrace | Exception class tracking list (Throwable.class by default) |
exceptionsToIgnore | Excluded exception types |
Note: private method is not supported for annotation method buried points.
be careful:
- blockHandler / blockHandlerClass: blockHandler corresponds to the name of the function handling BlockException. Optional. The access scope of blockHandler function needs to be public, the return type needs to match the original method, the parameter type needs to match the original method, and finally add an additional parameter with the type of BlockException. The blockHandler function needs to be in the same Class as the original method by default. If you want to use functions of other classes, you can specify blockHandlerClass as the Class object of the corresponding Class. Note that the corresponding function must be static function, otherwise it cannot be parsed.
Official annotation supporting documents: Annotation support · alibaba/Sentinel Wiki · GitHub
2. Definition rules
@SpringBootApplication public class SentinelApplication { public static void main(String[] args) { SpringApplication.run(SentinelApplication.class, args); initFlowQpsRule(); } //Defines a maximum of 2 requests per second private static void initFlowQpsRule() { List<FlowRule> rules = new ArrayList<>(); FlowRule rule = new FlowRule(IUserServiceImpl.RESOURCE_NAME); // set limit qps to 2 rule.setCount(2); rule.setGrade(RuleConstant.FLOW_GRADE_QPS); rule.setLimitApp("default"); rules.add(rule); FlowRuleManager.loadRules(rules); } }
be careful FlowRule rule = new FlowRule(IUserServiceImpl.RESOURCE_NAME) Resource name
Important attributes of flow rule
parameter | describe | describe |
---|---|---|
resource | Resource name, which is the object of flow restriction rules | |
limitApp | Flow control refers to the calling source. If it is default, the calling source will not be distinguished | default, which means that the call source is not distinguished |
grade | Current limiting threshold type, QPS mode (1) or concurrent threads mode (0) | QPS mode |
count | Current limiting threshold | |
strategy | Call relation current limiting strategy: direct, link and Association | According to the resource itself (direct) |
controlBehavior | Flow control effect (direct rejection, Warm Up, uniform queuing) | Direct rejection |
clusterMode | Cluster current limiting | no |
3. Whether the inspection rules are effective
@RestController public class UserController { @Autowired private IUserService userService; @GetMapping("/user/getUserByName") public String getUserByName(String userName){ return userService.selectUserByName(userName); } }
Browser access address localhost:9201/user/getUserByName?userName = Xiaohei
The current limit is triggered after quickly refreshing the interface for several times
At the same time, observe the cluster link of the console
summary
Sentinel has powerful functions, which is certainly not what we can accommodate in an article. This article only provides an introductory case. We will continue to learn other knowledge of sentinel later.
PS: I've seen it here. Give me a compliment, Yanzu!