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:

  1. Define the resources
  2. Define the rules
  3. 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:

  1. Define the resources
  2. Define the rules
  3. 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 processingBlockExceptionFunction name of
blockHandlerClass Of dealing with the classClassObject, the function must bestaticfunction
fallback Provided when an exception is thrownfallbackProcessing logic
defaultFallback Used as the default fallback method
fallbackClass The exception classClassObject, the function must bestaticfunction
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 / blockHandlerClassblockHandlerCorresponding processingBlockExceptionThe 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 classblockHandlerClassOf the corresponding classClassObject, 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!