This is the 11th day of my participation in the First Challenge 2022
- Microservices: Spring Cloud Gateway integrated with Sentinel flow limiting
In the Spring Cloud Gateway, we have already used Sentinel to limit the flow, but we have not studied Sentinel in detail, so today we need to make up for this knowledge.
Without further ado, let’s begin today’s lesson.
Sentinel introduces
Sentinel is a lightweight and highly available flow control component that is open source by Ali middleware team and oriented to distributed service architecture. It mainly takes traffic as the entry point and helps users protect the stability of services from multiple dimensions such as flow control, fuse downgrade and system load protection.
1. Basic concept of Sentinel
- resources
Resources are the key concept of Sentinel. It can be anything in a Java application, for example, a service provided by the application, or another application invoked by the application, or even a piece of code.
Any code defined through the Sentinel API is a resource that can be protected by Sentinel. In most cases, resources can be identified using method signatures, urls, and even service names as resource names.
- The rules
The rules set around the real-time status of resources can include flow control rules, fuse degrade rules, and system protection rules. All rules can be dynamically adjusted in real time.
2. The Sentinel features
Sentinel has the following characteristics:
-
Rich application scenarios: Sentinel has undertaken the core scenarios of Alibaba’s double Eleven traffic drive in the past decade, such as SEC killing (i.e. burst traffic control within the range of system capacity), message peaking and valley filling, cluster flow control, real-time fusing of unavailable downstream applications, etc
-
Perfect real-time monitoring: Sentinel Colleague provides real-time monitoring capabilities that allow you to see from the console the performance of a single machine connected to an application in seconds, or even a small cluster of 500 machines
-
Extensive open source ecosystem: Sentinel provides out-of-the-box integration modules with other frameworks/libraries, such as SpringCloud,Dubbo,gRPC, and you can quickly access Sentinel by introducing responsive dependencies and simple configuration
-
Perfect SPI extension Point: Sentinel provides an easy-to-use, perfect SPI extension interface that can be implemented to quickly customize logic, such as custom rule management, adaptation to dynamic data sources, etc
3. Sentinel VS Hystrix
What’s the difference between Sentinel and Hystrix?
Hystrix’s downsides:
- You need to manually build a monitoring platform
- There is no web interface that allows us to configure more granular flow control, rate control, fuses, downgrades, etc
- Hystrix’s common thread pool isolation causes large overhead of thread switching up and down.
Hystrix focuses on fault tolerance with isolation and fuses, calls that time out or are fuses fail quickly, and provides fallback mechanisms.
Sentinel focuses on:
- Diversified flow control
- Fusing the drop
- System load protection
- Real-time monitoring and console
Project integration
Sentinel can be simply divided into the Sentinel core library and the Dashboard console. The core library does not rely on Dashboard, but it works best with Dashboard.
- Core Library (Java client) : A runtime environment that is independent of any framework/library and can run on Java 8 and above, with good support for frameworks such as Dubbo/Spring Cloud.
- Console (Dashboard) : The Dashboard is mainly responsible for managing push rules, monitoring, and managing machine information.
It says that resources are the key concept of Sentinel and the use of Sentinel for resource conservation is divided into the following steps:
- Define the resources
- Define the rules
- Verify that the rules are in effect
After reading so many concepts above, I feel bald, so let’s give it a try.
1. Start the download
We can download it from https://github.com/alibaba/Sentinel/releases sentinel – dashboard – $version. The jar package.
We can launch the downloaded JAR package with the following command:
Java - Dserver. Port = 8718 - jar sentinel - dashboard - 1.8.3. JarCopy the code
-dserver. port=8718 Specifies the console port
The login address of the browser is http://localhost:8718. The default user name and password are sentinel/sentinel
And when you log in, it’s like this, it’s empty, so we’re going to see how it works.
2. How to integrate
1. Add dependencies
<! -- 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>
Copy the code
2. Add the Sentinel configuration
server:
port: 9201
spring:
application:
# app name
name: cloud-sentinel
cloud:
sentinel:
transport:
# console address
dashboard: 127.0. 01.: 8718
Copy the code
3. Test interface
@RestController
public class TestController {
@GetMapping("/testA")
public Object testA(a){
return "testA......";
}
@GetMapping("/testB")
public Object testB(a){
return "testB......"; }}Copy the code
4. Start the project and access the console
A visit to the Sentinel control station revealed that it was still empty.
It turned out that Sentinel console had a lazy loading mechanism, and we needed to access our service interface once before the console would display relevant information
Let’s access the interface localhost:9201/testA
Refreshing the Sentinel console again, I found a lot of request-related information
We can also in the spring that is configured in the configuration file. The cloud. The sentinel. Eager: true attribute to cancel the console lazy loadingCopy the code
At this stage, the project has only successfully integrated Sentinel and opened the console. Related operations on the console will not be discussed in this article and will be studied in the next article.
Use case
As mentioned above, Sentinel is used for resource conservation. It is mainly divided into the following steps:
- Define the resources
- Define the rules
- Verify that the rules are in effect
1. Define resources
There are several ways to define a resource: to throw an exception, to return a Boolean, to annotate a resource, and so on. We won’t go through them all. You can see basic-api-resource-rule (sentinelguard.io)
Here we use annotations to define resources. Sentinel provides the @SentinelResource annotation for defining resources and an extension to AspectJ for automatically defining resources, handling blockExceptions, and so on.
Since we are Sentinel via Spring Cloud Alibaba, we can use @SentinelResource annotations without additional configuration, otherwise we would need to introduce the following dependencies:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-annotation-aspectj</artifactId>
<version>x.y.z</version>
</dependency>
Copy the code
Let’s look at the use case for 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}";
}
FlowException: null FlowException: null FlowException: null FlowException: null
public String selectUserByNameBlockHandler(String username, BlockException ex)
{
System.out.println("SelectUserByNameBlockHandler abnormal information." + ex.getMessage());
return "{"code":"500","msg":"" + username + "Service traffic control processing"}";
}
// Add a Throwable parameter to the function signature
public String selectUserByNameFallback(String username, Throwable throwable)
{
System.out.println(SelectUserByNameFallback Exception message: + throwable.getMessage());
return "{"code":"500","msg":"" + username + "Service fuse degradation processing"}"; }}Copy the code
The @sentinelResource annotation contains the following properties:
parameter | describe |
---|---|
value | Resource name, required (cannot be empty) |
entryType | Resource invocation direction, optional (default isEntryType.OUT ) |
resourceType | Classification of resources |
blockHandler | Corresponding processingBlockException Function name of |
blockHandlerClass | Of dealing with the classClass Object, the function must bestatic function |
fallback | Provided when an exception is thrownfallback Processing logic |
defaultFallback | Used as the default fallback method |
fallbackClass | The exception classClass Object, the function must bestatic function |
exceptionsToTrace | Exception class trace list (default throwable.class) |
exceptionsToIgnore | The type of exception that is excluded |
Note: The annotation method does not support the private method.
Note:
blockHandler
/blockHandlerClass
:blockHandler
Corresponding processingBlockException
The optional function name of the The access range of the blockHandler function must bepublic
, the return type needs to match the original method, and the parameter type needs to match the original method and add an extra parameter at the end, of typeBlockException
. The blockHandler function needs to be in the same class as the original method by default. You can specify if you want to use a function from another classblockHandlerClass
Of the corresponding classClass
Object, note that the corresponding function must be static, otherwise it cannot be parsed.
Official annotation support documentation: Annotation Support · Alibaba /Sentinel Wiki · GitHub
2. Define 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(a) {
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); }}Copy the code
Note FlowRule rule = new FlowRule (IUserServiceImpl RESOURCE_NAME) resource nameCopy the code
Important properties of flow control rules
parameter | describe | describe |
---|---|---|
resource | The resource name is the object of the traffic limiting rule | |
limitApp | Call source for flow control. If it is Default, call source is not distinguished | Default: indicates that the call source is not distinguished |
grade | Flow limiting threshold type, QPS mode (1) or Number of concurrent threads mode (0) | QPS model |
count | Current limiting threshold | |
strategy | Call relationship traffic limiting policies: direct, link, and association | According to the resource itself (direct) |
controlBehavior | Flow control effect (direct rejection, Warm Up, uniform queuing) | Direct refused to |
clusterMode | Whether to restrict traffic in a cluster | no |
3. Check whether the rule takes effect
@RestController
public class UserController {
@Autowired
private IUserService userService;
@GetMapping("/user/getUserByName")
public String getUserByName(String userName){
returnuserService.selectUserByName(userName); }}Copy the code
Browser to access the address localhost: 9201 / user/getUserByName? The userName = black
Traffic limiting is triggered after the interface is refreshed for several times
Meanwhile, observe the console cluster point link
conclusion
Sentinel is too powerful to fit in a single article. This article is just a primer, and we will continue to learn more about Sentinel later.
PS: Now that you’ve seen it, give it a thumbs up, Daniel!