当前位置:网站首页>Alibaba sentinel basic operation

Alibaba sentinel basic operation

2022-07-24 20:20:00 Ordinary people zzz~

One 、Sentinel brief introduction

With the popularity of microservices , Stability between services and services is becoming more and more important .Sentinel Distributed oriented 、 Traffic management component of multilingual isomerization service architecture , The main pointcut is traffic , from Traffic routing 、 flow control 、 Traffic shaping 、 Fusing the drop 、 System adaptive overload protection 、 Hot spot flow protection And other dimensions to help developers ensure the stability of micro services .

Sentinel In two parts :

  • Core library (Java client ) Don't rely on any framework / library , Can run on all Java Runtime environment , At the same time Dubbo / Spring Cloud And other frameworks also have better support .
  • Console (Dashboard) be based on Spring Boot Development , It can run directly after packing , No additional Tomcat Etc. Application containers .

Two 、Sentinel Basic concepts

2.1 resources (Resource)

Resources are Sentinel Key concepts of . It can be Java Anything in the application , for example , Services provided by applications , Or services provided by other applications called by the application , It could even be a piece of code .

2.2 The rules (Rule)

Rules around the real-time state of resources , It can include flow control rules 、 Fusing degradation rules and system protection rules . All rules can be adjusted dynamically and in real time .

Sentinel Types of rules :

  1. Flow control rules (FlowRule);
  2. Fusing degradation rules (DegradeRule);
  3. System protection rules (SystemRule);
  4. Source access control rules (AuthorityRule);
  5. Hot spot parameter rules (ParamFlowRule);

2.3 slot (Slot Chain)

Sentinel The workflow of the is expanded around the slot chain composed of slots . Every Slot All have their own functions , Through a certain sequence of arrangement , To achieve the ultimate purpose of current limiting and degradation .

Sentinel The built-in slot has NodeSelectorSlot、ClusterBuilderSlot、StatisticsSlot、ParamFlowSlot、SystemSlot、AuthoritySlot、FlowSlot、DegradeSlot. Of course, it also supports custom slots ,Sentinel take com.alibaba.csp.sentinel.slotchain.ProcessorSlot As SPI Interface (1.7.2 Version before com.alibaba.csp.sentinel.slotchain.SlotChainBuilder As SPI), bring Slot Chain With the ability to expand .

2.4 Call link context (Context)

Context Throughout all of the links in a call Entry.Context Maintain the metadata of the current call chain : Entry node 、 This time, call the link node 、 Call source and other information , adopt ThreadLocal Pass on .

2.5 Entry

Entry Refer to Sentinel Whether the request passes a certificate of flow restriction . Every time you execute SphU.entry() or SphO.entry() Will return to one Entry To the caller . At the end of the resource call, you need entry.exit().Entry Contains the resource name 、curNode( Current statistics node )、originNode( Source statistics node ) Etc .

2.6 node (Node)

node . stay Sentinel The objects that save statistical data in 4 Kind of :

  1. StatisticNode: Statistics node , The most basic statistical node , It contains two sliding window structures of second level and minute level .
  2. DefaultNode: Link nodes , It is used to count the data of a resource on the call link , Maintain the tree structure .
  3. ClusterNode: Cluster node , It is used to count the global data of each resource ( Call links are not distinguished ), And storing the call data differentiated by source of the resource .
  4. EntranceNode: Entry node , Special link nodes , Corresponding to a certain Context All call data of the entry .

3、 ... and 、Sentinel Work flow

stay Sentinel Inside , All resources correspond to an asset name and a Entry. Entry It can be automatically created by adapting to the mainstream framework , It can also be annotated or called API According to create ; every last Entry At the time of creation , It will also create a series Function slot (slot chain), These slots have different responsibilities , Build through the responsibility chain , The overall framework is as follows :

 Insert picture description here

these slot (slot chain) Have different responsibilities .

  • NodeSelectorSlot: The path responsible for collecting resources , And the call path of these resources , Store in a tree structure , Used to limit the flow according to the call path 、 Downgrade .
  • ClusterBuilderSlot: Statistics used to store assets , And caller information , for example , Of this resource RT( Mean response time )、QPS、Thread Count wait , This information will be used as a multi-dimensional limit 、 The basis of the downgrade .
  • StatisticsSlot: Used to record 、 Statistics of different dimensions of runtime Indicator monitoring information .
  • ParamFlowSlot: Used for resource configuration hotspot parameters 、 Current limiting rules and the previous slot The state of Statistics , To control the flow .
  • SystemSlot: Through the state of the system , for example load1 etc. , To control the total inlet flow .
  • AuthoritySlot: According to the configured black and white list and call source information , To do black and white list control .
  • FlowSlot: It is used according to the preset current limiting rules and the front slot The state of Statistics , To control the flow .
  • DegradeSlot: Through statistics and preset rules , To do the fusing degradation .

Custom slot (slot chain)

Sentinel take com.alibaba.csp.sentinel.slotchain.ProcessorSlot As SPI Interface (1.7.2 Version before com.alibaba.csp.sentinel.slotchain.SlotChainBuilder As SPI), bring Slot Chain With the ability to expand .

You can add your own custom slot And choreograph slot The order between , So that we can give Sentinel Add custom features .

 Insert picture description here

The order of the default processor slots

// NodeSelectorSlot
public static final int ORDER_NODE_SELECTOR_SLOT = -10000;
// ClusterBuilderSlot
public static final int ORDER_CLUSTER_BUILDER_SLOT = -9000;
// LogSlot
public static final int ORDER_LOG_SLOT = -8000;
// StatisticsSlot
public static final int ORDER_STATISTIC_SLOT = -7000;
// AuthoritySlot
public static final int ORDER_AUTHORITY_SLOT = -6000;
// SystemSlot
public static final int ORDER_SYSTEM_SLOT = -5000;
// FlowSlot
public static final int ORDER_FLOW_SLOT = -2000;
// DegradeSlot
public static final int ORDER_DEGRADE_SLOT = -1000;

Four 、 Resources and rules

What we call resources , It could be anything , service , Methods in service , Even a piece of code . Use Sentinel To protect resources , It is mainly divided into several steps :

  1. Define resources
  2. Define the rules
  3. Check if the rules are in effect

First, define the resources that may need to be protected , Then configure the rules . It can also be understood as , As long as there are resources , We can flexibly define various flow control rules at any time . When coding , Just consider whether the code needs to be protected , If you need protection , Define it as a resource .

For mainstream frameworks , We offer adaptation , Just follow the instructions in the adapter ,Sentinel The services provided will be defined by default , Methods are resources .

4.1 Define resources

  1. Mode one : Default adaptation of the mainstream framework
    To reduce the complexity of development , We are interested in most mainstream frameworks , for example Web Servlet、Dubbo、Spring Cloud、gRPC、Spring WebFlux、Reactor And so on have done the adaptation . Just rely on your to integrate conveniently Sentinel. You can see :【 Adaptation of the mainstream framework 】.

  2. Mode two : Define resources by throwing exceptions
    SphU Contains try-catch Style API. In this way , It will be thrown when the resource is restricted BlockException. You can catch exceptions at this time , Logic processing after current limiting . The sample code is as follows :

// 1.5.0  The version is beginning to take advantage of  try-with-resources  characteristic 
//  Resource name can use any string with business semantics , For example, method name 、 Interface name or other uniquely identifiable string .
try (Entry entry = SphU.entry("resourceName")) {
    
	//  Protected business logic 
	// do something here...
} catch (BlockException ex) {
    
	//  Resource access blocked , Be restricted or degraded 
	//  Do the corresponding processing operation here 
}

SphU.entry(xxx) Need and entry.exit() Methods appear in pairs , Match calls , Otherwise, the call chain record will be abnormal , Throw out ErrorEntryFreeException abnormal .

          Be careful :
         1. if entry Is passed in Hot spot parameters , that exit You must also bring the corresponding parameters (exit(count, args)), Otherwise, there may be statistical errors .
         2. You can't use try-with-resources The way .
         3. In addition, through Tracer.trace(ex) To count the abnormal information , because try-with-resources In the syntax catch The problem of call order , It will result in the failure to correctly count the number of exceptions , Therefore, it is not allowed to count abnormal information in try-with-resources Of catch Call in block Tracer.trace(ex).

  1. Mode three : Returns the Boolean way to define resources
    SphO Provide if-else Style API. In this way , When the resource has been restricted, it will return to false, At this time, according to the return value , Logic processing after current limiting . The sample code is as follows :
//  Resource name can use any string with business semantics 
if (SphO.entry(" Custom resource name ")) {
    
	//  Make sure that finally Will be performed 
	try {
    
		/** *  Protected business logic  */
	} finally {
    
		SphO.exit();
	}
} else {
    
	//  Resource access blocked , Be restricted or degraded 
	//  Carry out corresponding processing operations 
}
  1. Mode 4 : Annotation defines resources
    Sentinel Supported by @SentinelResource Annotations define resources and configure blockHandler and fallback Function to limit the current ( Downgrade / Fuse ) To deal with . Example :
//  The original business approach .
@SentinelResource(value="resource-name", blockHandler = "blockHandlerForGetUser")
public User getUserById(String id) {
    
    throw new RuntimeException("getUserById command failed");
}

// blockHandler  function , The original method call is throttled / Downgrade / Called when the system is protected 
public User blockHandlerForGetUser(String id, BlockException ex) {
    
    return new User("admin");
}

Be careful : blockHandler The function will be Current limiting / Downgrade / System protection Called when , and fallback Function for all types of exceptions . About blockHandler and fallback The form of function requires , For more guidance, see 【Sentinel Annotations support documentation 】.

  1. Methods five : Asynchronous call support
    Sentinel Support asynchronous call link statistics . In an asynchronous call , Need to pass through SphU.asyncEntry(xxx) Method to define resources , And usually needs to be invoked in an asynchronous callback function exit Method . Here is a simple example :
try {
    
    AsyncEntry entry = SphU.asyncEntry(resourceName);

    //  Asynchronous call .
    doAsync(userId, result -> {
    
        try {
    
            //  Handle the result of the asynchronous call here .
        } finally {
    
            //  At the end of the callback  exit.
            entry.exit();
        }
    });
} catch (BlockException ex) {
    
    // Request blocked.
    // Handle the exception (e.g. retry or fallback).
}

SphU.asyncEntry(xxx) Will not affect the present ( Calling thread ) Of Context, So here are two entry On the call chain is a level relationship ( On the same floor ), Instead of nesting :

// The call chain is similar to :
// -parent
// —asyncResource
// —syncResource
asyncEntry = SphU.asyncEntry(asyncResource);
entry = SphU.entry(normalResource);

If you need to nest other resource calls in an asynchronous callback ( Whether it's entry still asyncEntry), Just use Sentinel Context switching function provided , To pass through in a corresponding place ContextUtil.runOnContext(context, f) Conduct Context Transformation , Transfer the corresponding resources to Context Switch to generated asynchrony Context, To maintain the correct call link relationship . Examples are as follows :

public void handleResult(String result) {
    
    Entry entry = null;
    try {
    
        entry = SphU.entry("handleResultForAsync");
        // Handle your result here.
    } catch (BlockException ex) {
    
        // Blocked for the result handler.
    } finally {
    
        if (entry != null) {
    
            entry.exit();
        }
    }
}

public void someAsync() {
    
    try {
    
        AsyncEntry entry = SphU.asyncEntry(resourceName);

        // Asynchronous invocation.
        doAsync(userId, result -> {
    
            //  Context transformation in asynchronous callbacks , adopt  AsyncEntry  Of  getAsyncContext  Method to get asynchronous  Context
            ContextUtil.runOnContext(entry.getAsyncContext(), () -> {
    
                try {
    
                    //  Normal resource calls are nested here .
                    handleResult(result);
                } finally {
    
                    entry.exit();
                }
            });
        });
    } catch (BlockException ex) {
    
        // Request blocked.
        // Handle the exception (e.g. retry or fallback).
    }
}

The call chain is similar to :

-parent
---asyncInvocation
-----handleResultForAsync

Detailed examples :

public class AsyncEntryDemo {
    

    private void invoke(String arg, Consumer<String> handler) {
    
        CompletableFuture.runAsync(() -> {
    
            try {
    
                TimeUnit.SECONDS.sleep(3);
                String resp = arg + ": " + System.currentTimeMillis();
                handler.accept(resp);
            } catch (Exception ex) {
    
                ex.printStackTrace();
            }
        });
    }

    private void anotherAsync() {
    
        try {
    
            final AsyncEntry entry = SphU.asyncEntry("test-another-async");

            CompletableFuture.runAsync(() -> {
    
                ContextUtil.runOnContext(entry.getAsyncContext(), () -> {
    
                    try {
    
                        TimeUnit.SECONDS.sleep(2);
                        // Normal entry nested in asynchronous entry.
                        anotherSyncInAsync();

                        System.out.println("Async result: 666");
                    } catch (InterruptedException e) {
    
                        // Ignore.
                    } finally {
    
                        entry.exit();
                    }
                });
            });
        } catch (BlockException ex) {
    
            ex.printStackTrace();
        }
    }

    private void fetchSync() {
    
        Entry entry = null;
        try {
    
            entry = SphU.entry("test-sync");
        } catch (BlockException ex) {
    
            ex.printStackTrace();
        } finally {
    
            if (entry != null) {
    
                entry.exit();
            }
        }
    }

    private void fetchSyncInAsync() {
    
        Entry entry = null;
        try {
    
            entry = SphU.entry("test-sync-in-async");
        } catch (BlockException ex) {
    
            ex.printStackTrace();
        } finally {
    
            if (entry != null) {
    
                entry.exit();
            }
        }
    }

    private void anotherSyncInAsync() {
    
        Entry entry = null;
        try {
    
            entry = SphU.entry("test-another-sync-in-async");
        } catch (BlockException ex) {
    
            ex.printStackTrace();
        } finally {
    
            if (entry != null) {
    
                entry.exit();
            }
        }
    }

    private void directlyAsync() {
    
        try {
    
            final AsyncEntry entry = SphU.asyncEntry("test-async-not-nested");

            this.invoke("abc", result -> {
    
                // If no nested entry later, we don't have to wrap in `ContextUtil.runOnContext()`.
                try {
    
                    // Here to handle the async result (without other entry).
                } finally {
    
                    // Exit the async entry.
                    entry.exit();
                }
            });
        } catch (BlockException e) {
    
            // Request blocked, handle the exception.
            e.printStackTrace();
        }
    }

    private void doAsyncThenSync() {
    
        try {
    
            // First we call an asynchronous resource.
            final AsyncEntry entry = SphU.asyncEntry("test-async");
            this.invoke("abc", resp -> {
    
                // The thread is different from original caller thread for async entry.
                // So we need to wrap in the async context so that nested invocation entry
                // can be linked to the parent asynchronous entry.
                ContextUtil.runOnContext(entry.getAsyncContext(), () -> {
    
                    try {
    
                        // In the callback, we do another async invocation several times under the async context.
                        for (int i = 0; i < 7; i++) {
    
                            anotherAsync();
                        }

                        System.out.println(resp);

                        // Then we do a sync (normal) entry under current async context.
                        fetchSyncInAsync();
                    } finally {
    
                        // Exit the async entry.
                        entry.exit();
                    }
                });
            });
            // Then we call a sync resource.
            fetchSync();
        } catch (BlockException ex) {
    
            // Request blocked, handle the exception.
            ex.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception {
    
        initFlowRule();

        AsyncEntryDemo service = new AsyncEntryDemo();

        // Expected invocation chain:
        //
        // EntranceNode: machine-root
        // -EntranceNode: async-context
        // --test-top
        // ---test-sync
        // ---test-async
        // ----test-another-async
        // -----test-another-sync-in-async
        // ----test-sync-in-async
        ContextUtil.enter("async-context", "originA");
        Entry entry = null;
        try {
    
            entry = SphU.entry("test-top");
            System.out.println("Do something...");
            service.doAsyncThenSync();
        } catch (BlockException ex) {
    
            // Request blocked, handle the exception.
            ex.printStackTrace();
        } finally {
    
            if (entry != null) {
    
                entry.exit();
            }
            ContextUtil.exit();
        }

        TimeUnit.SECONDS.sleep(20);
    }

    private static void initFlowRule() {
    
        // Rule 1 won't take effect as the limitApp doesn't match.
        FlowRule rule1 = new FlowRule()
            .setResource("test-another-sync-in-async")
            .setLimitApp("originB")
            .as(FlowRule.class)
            .setCount(4)
            .setGrade(RuleConstant.FLOW_GRADE_QPS);
        // Rule 2 will take effect.
        FlowRule rule2 = new FlowRule()
            .setResource("test-another-async")
            .setLimitApp("default")
            .as(FlowRule.class)
            .setCount(5)
            .setGrade(RuleConstant.FLOW_GRADE_QPS);
        List<FlowRule> ruleList = Arrays.asList(rule1, rule2);
        FlowRuleManager.loadRules(ruleList);
    }
}

4.2 Define the rules

Sentinel All rules of can be dynamically queried and modified in memory state , The amendment takes effect immediately after . meanwhile Sentinel It also provides related API, For you to customize your own rules and Strategies .

Sentinel The following rules are supported : Flow control rules 、 Fusing degradation rules 、 System protection rules 、 Source access control rules and Hot spot parameter rules .

4.3 Flow control rules (FlowRule)

Important attributes :

Field explain The default value is
resource Resource name , Resource name is the object of current restriction rule
count Current limiting threshold
grade Current limiting threshold type ,QPS Or thread count mode QPS Pattern
limitApp The call source of the flow control default, Represents that the call source is not distinguished
strategy Call relationship current limiting policy : direct 、 link 、 relation According to the resource itself ( direct )
controlBehavior Flow control effect ( Direct refused to / Waiting in line / Slow start mode ), Current limiting by call relationship is not supported Direct refused to

The same resource can have Multiple Current limiting rules .

Define flow control rules by code

After understanding the definition of the above rules , We can do it by calling FlowRuleManager.loadRules() Method to define the flow control rules in a hard coded way , such as :

private static void initFlowQpsRule() {
    
    List<FlowRule> rules = new ArrayList<>();
    FlowRule rule1 = new FlowRule();
    rule1.setResource(resource);
    // Set max qps to 20
    rule1.setCount(20);
    rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
    rule1.setLimitApp("default");
    rules.add(rule1);
    FlowRuleManager.loadRules(rules);
}

be based on QPS/ Flow control of concurrency number

There are two main statistical types of flow control :

  1. Count the number of threads
  2. Statistics QPS.

Type by FlowRule.grade Field to define . among ,0 It means to limit the flow according to the number of concurrent ,1 On behalf of QPS To control the flow . Number of threads 、QPS value , It's all by StatisticSlot Obtained by real-time statistics . You can view real-time statistics through the following command :

curl http://localhost:8719/cnode?id=resourceName

The output format is as follows :

 Insert picture description here
among :

  • thread: Represents the number of threads currently processing the resource ;
  • pass: Represents a request to arrive in one second ;
  • blocked: Represents the number of requests controlled by flow in one second ;
  • success: Represents the request successfully processed in one second ;
  • total: Represents the sum of incoming requests and blocked requests in less than one second ;
  • RT: Represents the average response time of the resource in one second ;
  • 1m-pass: It's a request that comes in a minute ;
  • 1m-block: It's a request blocked in a minute ;
  • 1m-all: Is the sum of incoming requests and blocked requests in one minute ;
  • exception: Is the sum of the exceptions of the business itself in one second .

Flow control based on call relation

The calling relationship includes The caller 、 Called party ; Method may call other methods , Form a call link The hierarchy of .Sentinel adopt NodeSelectorSlot Establish the call relationship between different resources , And through ClusterNodeBuilderSlot Record real-time statistics for each resource .

With the statistics of the calling link , We can derive a variety of flow control methods .

ContextUtil.enter(resourceName, origin) Methods origin Parameter indicates the identity of the caller . This information will be in ClusterBuilderSlot Is counted . The following commands can be used to display the call data of different callers to the same resource :

curl http://localhost:8719/origin?id=nodeA

Call data example :
 Insert picture description here
The above command shows the resource name nodeA Statistics of resources called by two different callers .

In the current limiting rules limitApp Field is used to control the flow according to the caller . There are three options for the value of this field , Corresponding to different scenes :

  • default: Indicates that the caller is not distinguished , Requests from any caller will be counted for throttling . If the total number of calls to this resource name exceeds the threshold defined by this rule , Then the current limit is triggered .
  • {some_origin_name}: Represents a specific caller , Only requests from this caller will have traffic control . for example NodeA Configured one for the caller caller1 The rules of , Then if and only if from caller1 Yes NodeA The request will trigger the flow control .
  • other: For division {some_origin_name} The traffic of other callers is controlled . for example , resources NodeA Configured one for the caller caller1 The current limiting rules of , At the same time, a caller is configured as other The rules of , Then any one comes from non caller1 Yes NodeA Call to , No more than other Threshold defined by this rule .

The same resource name can be configured multiple The rules , The effective order of rules is :{some_origin_name} > other > default

Limit the current according to the call link entry : Link current limiting

NodeSelectorSlot The call link between resources is recorded in , These resources are accessed through a call relationship , Form a call tree with each other . The root node of this tree is a node named machine-root The virtual node of , The entry of the call chain is the child node of the virtual node .

A typical call tree is shown in the figure below :
 Insert picture description here
In the figure above, it comes from the entrance Entrance1 and Entrance2 All requests are called to resources NodeA,Sentinel It is allowed to limit the flow of resources only according to the statistical information of a certain entry . For example, we can set FlowRule.strategy by RuleConstant.CHAIN, Simultaneous setting FlowRule.ref_identity by Entrance1 To indicate that only from the entrance Entrance1 The call will be recorded to NodeA In the current limiting statistics of , And yes, from Entrance2 Callers are indifferent .

The entry of the call chain is through API Method ContextUtil.enter(name) Defined .

Resource flow control with relationship : Associated flow control

When there is Resource contention or dependency When , These two resources have relation .

For example, there is a competition between the read operation and the write operation of the same field in the database , Reading too fast will affect the speed of writing , Writing too fast will affect the speed of reading . If you let read and write operations compete for resources , Then the cost of contention itself will reduce the overall throughput . Association current limiting can be used to avoid excessive contention between resources with association relationship , for instance ,read_db and write_db These two resources represent database reading and writing respectively , We can give read_db Set the current limiting rule to achieve the purpose of write first : Set up FlowRule.strategy by RuleConstant.RELATE Simultaneous setting FlowRule.ref_identity by write_db. In this way, when the write operation is too frequent , Requests to read data are limited .

4.4 Fusing degradation rules (DegradeRule)

In addition to flow control , The unstable resources in the call link are Fusing the drop It is also one of the important measures to ensure high availability . A service often calls other modules , Maybe another remote service 、 database , Or a third party API etc. .

However , The stability of this dependent service is not guaranteed . If the dependent service is unstable , Request response times get longer , Then the response time of the method calling the service will be longer , Threads will pile up , Finally, the thread pool of the business itself may be exhausted , The service itself becomes unavailable .

So we need to deal with the unstable Weak dependence on service invocation Carry out fusing degradation , Temporarily cut off unstable calls , Avoid avalanche caused by local instability . Fuse degradation as a means to protect itself , Usually on the client side ( Calling end ) To configure .

Important attributes :

Field explain The default value is
resource Resource name , That is, the object of action of rules
grade Fusing strategy , Slow support Call proportion / Abnormal proportion / Heteroconstant strategy Slow call ratio
count Slow call critical in slow call proportional mode RT( Exceeding this value counts as a slow call ); Abnormal proportion / The corresponding threshold in the outlier mode
timeWindow Duration of fusing , Unit is s
minRequestAmount Minimum number of requests triggered by fusing , When the number of requests is less than this value, even if the exception ratio exceeds the threshold, it will not fuse (1.7.0 introduce )5
statIntervalMs Statistics duration ( Unit is ms), Such as 60*1000 Represents the minute level (1.8.0 introduce )1000 ms
slowRatioThreshold Slow call proportional threshold , Only slow call proportional mode works (1.8.0 introduce )

The same resource can have Multiple Demotion rules .

After understanding the definition of the above rules , We can do it by calling DegradeRuleManager.loadRules() Method to define the flow control rules in a hard coded way .

private static void initDegradeRule() {
    
    List<DegradeRule> rules = new ArrayList<>();
    DegradeRule rule = new DegradeRule(resource);
        .setGrade(CircuitBreakerStrategy.ERROR_RATIO.getType());
        .setCount(0.7); // Threshold is 70% error ratio
        .setMinRequestAmount(100)
        .setStatIntervalMs(30000) // 30s
        .setTimeWindow(10);
    rules.add(rule);
    DegradeRuleManager.loadRules(rules);
}

Fuse event monitoring

Sentinel Support registering custom event listener to monitor fuse state change events (state change event). Example :

EventObserverRegistry.getInstance().addStateChangeObserver("logging",
    (prevState, newState, rule, snapshotValue) -> {
    
        if (newState == State.OPEN) {
    
            //  Change to  OPEN state  Will carry the value of the trigger 
            System.err.println(String.format("%s -> OPEN at %d, snapshotValue=%.2f", prevState.name(),
                TimeUtil.currentTimeMillis(), snapshotValue));
        } else {
    
            System.err.println(String.format("%s -> %s at %d", prevState.name(), newState.name(),
                TimeUtil.currentTimeMillis()));
        }
    });

4.5 System protection rules (SystemRule)

Sentinel The system adaptive current limiting controls the flow at the application entrance from the overall dimension , Combined with the application of Load、CPU Usage rate 、 On average RT、 entrance QPS And the number of concurrent threads , Through adaptive flow control strategy , Make the system's inlet flow and the system's load reach a balance , Let the system run at the maximum throughput and ensure the overall stability of the system .

Important attributes :

Field explain The default value is
highestSystemLoad System load (load1) Trigger value , Used to trigger the adaptive control phase -1 ( Don't take effect )
avgRt Average response time for all inlet flows -1 ( Don't take effect )
maxThread The maximum number of concurrent entries -1 ( Don't take effect )
qps Of all entry resources QPS-1 ( Don't take effect )
highestCpuUsage Of the current system CPU Usage rate (0.0-1.0)-1 ( Don't take effect )

After understanding the definition of the above rules , We can do it by calling SystemRuleManager.loadRules() Method to define the flow control rules in a hard coded way :

private void initSystemProtectionRule() {
    
	List<SystemRule> rules = new ArrayList<>();
	SystemRule rule = new SystemRule();
	rule.setHighestSystemLoad(10);
	rules.add(rule);
	SystemRuleManager.loadRules(rules);
}

4.6 Source access control (AuthorityRule- Black and white list )

A lot of times , We need to limit whether resources pass through... Based on the caller , You can use it Sentinel Access control ( Black and white list ) The function of . The black and white list is based on the source of the resource request (origin) Restrict the passage of resources .

  • If the whitelist is configured, it can only be passed if the request source is in the whitelist ;
  • If the blacklist is configured, the request source will not pass when it is in the blacklist , The rest of the requests go through .

Important attributes :

Field explain The default value is
resource Resource name , That is, the object of the current limiting rule
limitApp The corresponding blacklist / White list , Different origin use , Separate , Such as appA,appB
strategy Limit mode ,AUTHORITY_WHITE For whitelist mode ,AUTHORITY_BLACK For blacklist mode AUTHORITY_WHITE White list mode

After understanding the definition of the above rules , We can do it by calling AuthorityRuleManager.loadRules() Method to define the flow control rules in a hard coded way :

private void initAuthorityRule() {
    
	AuthorityRule rule = new AuthorityRule();
	rule.setResource("test");
	rule.setStrategy(RuleConstant.AUTHORITY_WHITE);
	rule.setLimitApp("appA,appB");
	AuthorityRuleManager.loadRules(Collections.singletonList(rule));
}

4.7 Hot spot rules (ParamFlowRule)

What is the hot spot ? Hot spots are frequently accessed data . Most of the time, we want to count the most frequently visited data in a hotspot Top K data , And restrict their access . such as :

  • goods ID Is the parameter , Count the most frequently purchased items in a period of time ID And limit
  • user ID Is the parameter , For users who visit frequently over a period of time ID Limit

Hot spot parameter current limiting will count the hot spot parameters in the incoming parameters , and According to the configured current limiting threshold and mode , Restrict the flow of resource calls with hotspot parameters . Hot spot parameter current limiting can be regarded as a special flow control , Only valid for resource calls with hotspot parameters .

Sentinel utilize LRU Strategy statistics Most frequently visited recently Hotspot parameters , combination Token bucket algorithm For parameter level flow control .

To use the hot spot parameter current limiting function , The following dependencies need to be introduced :

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-parameter-flow-control</artifactId>
    <version>x.y.z</version>
</dependency>

Then configure the hot spot parameter current limiting rules for the corresponding resources , And in entry The corresponding parameters are passed in , It can make the current limiting of hot spot parameters effective .

notes : If you expand and register your own implementation SlotChainBuilder, And hope to use the hot spot parameter current limiting function , Can be in chain Insert it in a suitable place ParamFlowSlot.

So how to pass in the corresponding parameters so that Sentinel Statistics ? We can go through SphU Class entry Overload method to pass in :


public static Entry entry(String name, EntryType type, int count, Object... args) throws BlockException;

public static Entry entry(Method method, EntryType type, int count, Object... args) throws BlockException;

The last of them args Is the parameter to be passed in , More than one will be introduced in sequence . For example, to pass in two parameters paramA and paramB, Then you can :

// paramA in index 0, paramB in index 1.
//  If you need to configure exceptions or use cluster dimension flow , The parameter passed in only supports the basic type .
SphU.entry(resourceName, EntryType.IN, 1, paramA, paramB);

Be careful : if entry The hotspot parameter is passed in , that exit You must also bring the corresponding parameters (exit(count, args)), Otherwise, there may be statistical errors . The right example :

Entry entry = null;
try {
    
    entry = SphU.entry(resourceName, EntryType.IN, 1, paramA, paramB);
    // Your logic here.
} catch (BlockException ex) {
    
    // Handle request rejection.
} finally {
    
    if (entry != null) {
    
        entry.exit(1, paramA, paramB);
    }
}

about @SentinelResource Resources defined by annotation , If there are parameters on the method of annotation ,Sentinel They are passed in as parameters SphU.entry(res, args). For example, in the following methods uid and type Will serve as first and the second Parameters of the incoming Sentinel API, So it can be used to judge hotspot rules :

@SentinelResource("myMethod")
public Result doSomething(String uid, int type) {
    
  // some logic here...
}

Important attributes :

Field explain The default value is
resource Resource name , Required
count Current limiting threshold , Required
grade Current limiting mode QPS Pattern
durationInSec Count the window length ( The unit is in seconds ),1.6.0 Version starting support 1s
controlBehavior Flow control effect ( Support fast failure and uniform queuing mode ),1.6.0 Version starting support Fast failure
maxQueueingTimeMs Maximum waiting time in line ( Only in uniform queuing mode ),1.6.0 Version starting support 0ms
paramIdx Index of hotspot parameters , Required , Corresponding SphU.entry(xxx, args) Parameter index location in
paramFlowItemList Parameter exceptions , The current limiting threshold value can be set separately for the specified parameter value , Don't suffer from the front count Threshold limit . Only basic and string types are supported
clusterMode Is it a cluster parameter flow control rule false
clusterConfig Cluster flow control related configuration

After understanding the definition of the above rules , We can do it by calling ParamFlowRuleManager.loadRules() Method to define the flow control rules in a hard coded way :

private void initAuthorityRule() {
    
	ParamFlowRule rule = new ParamFlowRule(resourceName)
    							.setParamIdx(0)
    							.setCount(5);
	//  in the light of  int  Parameters of type  PARAM_B, Set the current limit separately  QPS  The threshold for  10, Not the global threshold  5.
	ParamFlowItem item = new ParamFlowItem().setObject(String.valueOf(PARAM_B))
    							.setClassType(int.class.getName())
    							.setCount(10);
	rule.setParamFlowItemList(Collections.singletonList(item));

	ParamFlowRuleManager.loadRules(Collections.singletonList(rule));
}

5、 ... and 、 Annotation support (@SentinelResource)

5.1 @SentinelResource

Sentinel Provides @SentinelResource Annotations are used to define resources , And provides AspectJ The extension of is used to automatically define resources 、 Handle BlockException etc. . Use Sentinel Annotation AspectJ Extension The following dependencies need to be introduced when using :

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-annotation-aspectj</artifactId>
    <version>x.y.z</version>
</dependency>

Be careful : Annotation embedding is not supported private Method .

@SentinelResource Used to define resources , And provides optional exception handling and fallback Configuration item . @SentinelResource The annotation contains the following properties :

  • value: Resource name , Required ( Can't be empty )
  • entryType:entry type , optional ( The default is EntryType.OUT)
  • blockHandler / blockHandlerClass: blockHandler Deal with BlockException The function name of , optional .
    • blockHandler The function access range needs to be public;
    • Return type needs to match the original method ;
    • The parameter type needs to match the original method and add an extra parameter , The type is BlockException;
    • blockHandler Function default needs to be in the same class as the original method .
    • If you want to use functions of other classes , You can specify blockHandlerClass For the corresponding class Class object , Note the corresponding function It's necessary by static function , Otherwise, it cannot be parsed .
  • fallbackfallback The name of the function , optional , Used to provide... When an exception is thrown fallback Processing logic .fallback Functions can be used for all types of exceptions ( except exceptionsToIgnore The types of exceptions excluded ) To deal with .fallback Function signature and location requirements :
    • The return value type must be the same as the return value type of the original function ;
    • Method parameter list should be consistent with the original function , Or maybe one more Throwable The parameter of type is used to receive the corresponding exception ;
    • fallback Function default needs to be in the same class as the original method .
    • If you want to use functions of other classes , You can specify fallbackClass For the corresponding class Class object , Note the corresponding function It's necessary by static function , Otherwise, it cannot be parsed .
  • defaultFallback(since 1.6.0): default fallback The name of the function , optional , Usually used for general purpose fallback Logic ( It can be used in many services or methods ). Default fallback Functions can be used for all types of exceptions ( except exceptionsToIgnore The types of exceptions excluded ) To deal with . If you configure fallback and defaultFallback, only fallback Will take effect .defaultFallback Function signature requirements :
    • The return value type must be the same as the return value type of the original function ;
    • Method parameter list needs to be empty , Or maybe one more Throwable The parameter of type is used to receive the corresponding exception ;
    • defaultFallback Function default needs to be in the same class as the original method .
    • If you want to use functions of other classes , You can specify fallbackClass For the corresponding class Class object , Note the corresponding function It's necessary by static function , Otherwise, it cannot be parsed .
  • exceptionsToIgnore(since 1.6.0): Used to specify which exceptions are excluded , It will not be included in the abnormal statistics , And will not enter fallback In the logic , But will throw out as is .

Specially , if blockHandler and fallback It's all configured , It is degraded by current limiting and thrown BlockException It will only enter blockHandler Processing logic . If not configured blockHandler、fallback and defaultFallback, When it is degraded by current limiting, it will BlockException Direct selling .

Example :

public class TestService {
    

    //  Corresponding  `handleException`  The function needs to be in  `ExceptionUtil`  Class , And must be  static  function .
    @SentinelResource(value = "test", blockHandler = "handleException", blockHandlerClass = {
    ExceptionUtil.class})
    public void test() {
    
        System.out.println("Test");
    }

    //  Primitive function 
    @SentinelResource(value = "hello", blockHandler = "exceptionHandler", fallback = "helloFallback")
    public String hello(long s) {
    
        return String.format("Hello at %d", s);
    }
    
    // Fallback  function , The signature of the function is the same as the original function or add one  Throwable  Parameters of type .
    public String helloFallback(long s) {
    
        return String.format("Halooooo %d", s);
    }

    // Block  Exception handling functions , One more parameter at the end  BlockException, The rest is consistent with the original function .
    public String exceptionHandler(long s, BlockException ex) {
    
        // Do some log here.
        ex.printStackTrace();
        return "Oops, error occurred at " + s;
    }
}

5.2 Project configuration

AspectJ

If your app uses AspectJ, Then you need to be in aop.xml The corresponding Aspect:

<aspects>
    <aspect name="com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect"/>
</aspects>

Spring AOP

If your app uses Spring AOP, You need to configure SentinelResourceAspect Register as a Spring Bean:

@Configuration
public class SentinelAspectConfiguration {
    

    @Bean
    public SentinelResourceAspect sentinelResourceAspect() {
    
        return new SentinelResourceAspect();
    }
}

6、 ... and 、Sentinel Console (Dashboard)

6.1 Dashboard

Sentinel The console contains the following functions :

  • ** Check the list of machines and their health :** collect Sentinel Heartbeat packets sent by the client , Used to determine if the machine is online .
  • ** monitor ( Single machine and cluster aggregation ):** adopt Sentinel Monitoring of client exposure API, Pull and aggregate application monitoring information regularly , Finally, it can realize real-time monitoring in seconds .
  • ** Rule management and push :** Unified management of push rules .
  • ** authentication :** Authentication is very important in the production environment . Here, each developer needs to customize according to their own actual situation .

Be careful :Sentinel The console currently only supports stand-alone deployment .Sentinel The console project provides Sentinel Complete set of functions , Not used as a production environment console out of the box , If you want to use it in the production environment, please customize and transform it according to the documents .

6.2 Launch the console

Start the console with the following command :

java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar

among -Dserver.port=8080 Is used to specify the Sentinel The console port is 8080.

Be careful : start-up Sentinel Console need JDK Version is 1.8 And above .

from Sentinel 1.6.0 rise ,Sentinel The console introduces basic login functions , The default username and password are sentinel.

The user can configure through the following parameters :

  • Dsentinel.dashboard.auth.username=sentinel The login user name used to specify the console is sentinel;
  • Dsentinel.dashboard.auth.password=123456 The login password used to specify the console is 123456; If you omit these two parameters , The default user and password are sentinel;
  • Dserver.servlet.session.timeout=7200 Is used to specify the Spring Boot Server side session The expiration time of , Such as 7200 Express 7200 second ;60m Express 60 minute , The default is 30 minute ;

You can also do it directly Spring properties File to configure .

6.3 Client Access Console

After the console starts , The client needs to access the console as follows .

6.3.1 introduce JAR package

The client needs to introduce Transport Module to Sentinel The console communicates . You can pom.xml introduce JAR package :

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-transport-simple-http</artifactId>
    <version>x.y.z</version>
</dependency>

6.3.2 Configure startup parameters

Boot in JVM Parameters -Dcsp.sentinel.dashboard.server=consoleIp:port Specify the console address and port . If you start multiple applications , You have to go through -Dcsp.sentinel.api.port=xxxx Specify client monitoring API The port of ( The default is 8719).

In addition to modify JVM Parameters , You can do the same with the configuration file . More detailed information is available 【 Start profile 】.

6.3.3 Trigger client initialization

Make sure the client has access ,Sentinel It will be initialized the first time the client calls , Start sending heartbeat packets to the console .

Be careful : You also need to introduce the corresponding Adaptation depends on , Otherwise, even if there are visits, they can't be Sentinel Statistics .

7、 ... and 、 Cluster flow control

reference :Alibaba Sentinel - Cluster flow control

8、 ... and 、 Gateway flow control

reference :Alibaba Sentinel - Gateway flow control

reference :https://sentinelguard.io/zh-cn/docs/introduction.html

原网站

版权声明
本文为[Ordinary people zzz~]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/205/202207242013324087.html