1. Introduction

In the previous article, we analyzed how Sentinel statistics data indicators. This paper mainly analyzes the function and implementation of some function slots on the call link, including system adaptive, blacklist control, flow control, fuse degrade four functions.

2. Sentinel function slot rule

2.1. Definition of rules

Before analyzing the various functional slots, take a look at Sentinel’s definition of rules.

Sentinel uses Rule to represent a Rule. Rule is an interface, and Rule has only one method, passCheck(), which indicates whether the Rule passes.

AbstractRule implements Rule as an abstract class that defines the resource and app to which the Rule belongs. All concrete rules inherit from that rule.

2.2. Rule loading or updating

After defining a specific rule, you need to load the rule to the system. The loading process is carried out by the rule manager. For example, if the system adaptive rule SystemRule is defined, the corresponding rule manager SystemRuleManager loads the rule. The following uses SystemRuleManager as an example to analyze the loading of rules.

Each rule manager has a rule change handler that inherits the SimplePropertyListener as a variable and does the associated updating when the rule changes. An inner class is defined in each rule manager as a concrete implementation of this variable, such as SystemRuleManager:

Private Final Static SystemPropertyListener Listener = new SystemPropertyListener(); Static Class SystemPropertyListener extends SimplePropertyListener<List<SystemRule>>{... }Copy the code

As you can see, SystemRuleManager creates a SystemPropertyListener, an inner class within it, as the handler for file changes.

The rule manager also defines a SentinelProperty, which represents the configuration information in Sentinel, in this case the rule for the configuration. The defined rule handler is then added to the rule, and when the rule changes, the corresponding rule handler is used for processing.

private static SentinelProperty<List<SystemRule>> currentProperty = new DynamicSentinelProperty<List<SystemRule>>();

currentProperty.addListener(listener);

Copy the code

In the case of SystemRule updates, after a rule is defined, a call to loadRules() of SystemRuleManager will update the rule.

public static void loadRules(List<SystemRule> rules) {
    currentProperty.updateValue(rules);
}
Copy the code

To call loadRules(), we call DynamicSentinelProperty’s updateValues() method:

 public boolean updateValue(T newValue) {
    if (isEqual(value, newValue)) {
        return false;
    }
    RecordLog.info("[DynamicSentinelProperty] Config will be updated to: " + newValue);

    value = newValue;
    for (PropertyListener<T> listener : listeners) {
        listener.configUpdate(newValue);
    }
    return true;
}
Copy the code

As you can see, DynamicSentinelProperty’s updateValues() method calls the configUpdate() method of the rule change handler, So how it is updated is the inner class SimplePropertyListener defined in each rule manager.

The above is the loading process of rules. The loading process of various rules is generally the same, except that the specific loading logic is updated by the SimplePropertyListener defined in the rule manager.

3. The system ADAPTS to traffic limiting

3.1. What is system adaptive current limiting

System protection rules control the incoming flow at the application level, and monitor application indicators from several dimensions, such as load of a single machine, CPU usage, average RT, incoming QPS and number of concurrent threads, so that the system can run as fast as possible in the maximum throughput and ensure the overall stability of the system.

System protection rules apply to the global dimension, not the resource dimension, and only apply to incoming traffic. Inbound traffic refers to the traffic entering the application (entrytype. IN), such as the requests received by the Web service or the Dubbo server.

System rules support the following modes:

  • Load adaptive (only for Linux/ UNIX-like machines) : Load1 of the system is used as an inspiration indicator to implement adaptive system protection. System protection (BBR phase) is triggered when system load1 exceeds the set heuristics value and the current number of concurrent threads in the system exceeds the estimated system capacity. The system capacity is estimated by the system maxQps * minRt. The reference values are typically CPU cores * 2.5.

  • CPU Usage (version 1.5.0+) : When the CPU usage exceeds the threshold, system protection is triggered (value range: 0.0 to 1.0).

  • Average RT: System protection is triggered when the average RT of all inlet traffic on a single machine reaches a threshold, in milliseconds. Number of concurrent threads: System protection is triggered when the number of concurrent threads for all incoming traffic on a single machine reaches a threshold.

  • Inlet QPS: System protection is triggered when the QPS of all inlet flows on a single machine reaches the threshold.

The above text is excerpted in sentinel official documents.

2.2. SystemRule

SystemRule indicates the rule definition of system adaptive protection. It defines parameters of load, CPU, QPS, RT, and Thread.

public class SystemRule extends AbstractRule {
    /**
     * negative value means no threshold checking.
     */
    private double highestSystemLoad = -1;
    /**
     * cpu usage, between [0, 1]
     */
    private double highestCpuUsage = -1;
    private double qps = -1;
    private long avgRt = -1;
    private long maxThread = -1;
}
Copy the code

2.3. SystemRuleManager

SystemRuleManager is the core class of system adaptive protection. It is responsible for managing system adaptive rules, including loading update rules and checking whether the current entry call meets the rules.

public class SystemRuleManager {

    private static volatile double highestSystemLoad = Double.MAX_VALUE;
    private static volatile double highestCpuUsage = Double.MAX_VALUE;
    private static volatile double qps = Double.MAX_VALUE;
    private static volatile long maxRt = Long.MAX_VALUE;
    private static volatile long maxThread = Long.MAX_VALUE;
    
    private static volatile boolean highestSystemLoadIsSet = false;
    private static volatile boolean highestCpuUsageIsSet = false;
    private static volatile boolean qpsIsSet = false;
    private static volatile boolean maxRtIsSet = false;
    private static volatile boolean maxThreadIsSet = false; /** * Whether the specified system rule exists, Whether the call SystemRuleManager. LoadRules () loading rule * / private static AtomicBoolean checkSystemStatus = new AtomicBoolean (false); */ private static SystemStatusListener statusListener = null; / / Private Final Static SystemPropertyListener Listener = new SystemPropertyListener(); / / Private Final Static SystemPropertyListener = new SystemPropertyListener(); /** * System rule changes after the processor, */ private static SentinelProperty<List<SystemRule>> currentProperty = new DynamicSentinelProperty<List<SystemRule>>(); /** * */ private final static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1, new NamedThreadFactory("sentinel-system-status-record-task".true));

    static {
        checkSystemStatus.set(false); statusListener = new SystemStatusListener(); / / timing task start after 5 SECONDS, every second, do a scheduler. The scheduleAtFixedRate (statusListener, 5, 1, TimeUnit. SECONDS); currentProperty.addListener(listener); }... }Copy the code

The main meanings of the above parameters are as follows:

  • The ten parameters defined above mainly describe the adaptive protection parameters of the system.
  • CheckSystemStatus: indicates whether system adaptive protection is required.
  • StatusListener: A task responsible for obtaining system operation parameters.
  • Listener: Processor after system rule changes.
  • CurrentProperty: indicates the current configuration file.
  • Scheduler: A scheduled task that runs statusListener.

Looking at the static code block, it basically initializes the scheduler, sets the tasks and frequencies to run, and adds the system rules handler to currentProperty.

The SystemRuleManager is responsible for the loading of rules, as discussed in section 2.

One of the most important methods in SystemRuleManager is checkSystem(), which verifies that incoming requests meet the system’s adaptive setting rules.

public static void checkSystem(ResourceWrapper resourceWrapper) throws BlockException { // Ensure the checking switch is On. // If no system rule is added, no check is requiredif(! checkSystemStatus.get()) {return; } / /forInbound traffic only // If the resource is not a system entry resource, no check is performedif(resourceWrapper.getType() ! = EntryType.IN) {return; } // ClusterNode is a class variable that is globally unique and generated after the class is loaded. // Total QPS double currentQps = Constants.ENTRY_NODE == null? 0.0: the ENTRY_NODE. SuccessQps ();if (currentQps > qps) {
        throw new SystemBlockException(resourceWrapper.getName(), "qps");
    }

    // total thread
    int currentThread = Constants.ENTRY_NODE == null ? 0 : Constants.ENTRY_NODE.curThreadNum();
    if (currentThread > maxThread) {
        throw new SystemBlockException(resourceWrapper.getName(), "thread");
    }

    double rt = Constants.ENTRY_NODE == null ? 0 : Constants.ENTRY_NODE.avgRt();
    if (rt > maxRt) {
        throw new SystemBlockException(resourceWrapper.getName(), "rt"); } // load. BBR algorithm. // If the load of the current machine is greater than the set valueif (highestSystemLoadIsSet && getCurrentSystemAvgLoad() > highestSystemLoad) {
        if(! checkBbr(currentThread)) { throw new SystemBlockException(resourceWrapper.getName(),"load");
        }
    }

    // cpu usage
    if (highestCpuUsageIsSet && getCurrentCpuUsage() > highestCpuUsage) {
        if(! checkBbr(currentThread)) { throw new SystemBlockException(resourceWrapper.getName(),"cpu"); }}}Copy the code

The checkSystem() logic is described above, and the implementation principle can be referred to the official documentation.

2.4. SystemSlot

SystemSlot is a slot for adaptive system protection. Adaptive protection verification is performed for each internal entry. SystemSlot is simple, mainly in the entry () method call SystemRuleManager. CheckSystem () method for the adaptive protection system of inspection, specific logic or in SystemRuleManager.

3. AuthoritySlot

The resource blacklist and whitelist determines whether the resource can pass based on the origin of the request. If a whitelist is configured, the resource can pass only when the request source is in the whitelist. If the blacklist is configured, the request source in the blacklist does not pass, and the rest of the requests pass.

3.1. AuthorityRule

AuthorityRule represents the rule for setting the blacklist and whitelist, which mainly includes two attribute Settings, one is the name of the source of the restriction, multiple sources are separated by commas. Also need to set restrictions when whitelist or blacklist.

private String limitApp;
private int strategy = RuleConstant.AUTHORITY_WHITE;
Copy the code

3.2. AuthorityRuleManager

The AuthorityRuleManager, like the SystemRuleManager in the previous section, is responsible for managing the loading of the blacklist and whitelist. Let’s take a look at the attribute definition:

Public final class AuthorityRuleManager {** * save permission configuration, */ private static Map<String, private static Map<String, Set<AuthorityRule>> authorityRules = new ConcurrentHashMap<>(); /** * Rule change handler */ private static final RulePropertyListener LISTENER = new RulePropertyListener(); Private static SentinelProperty<List<AuthorityRule>> currentProperty = new DynamicSentinelProperty<>(); static { currentProperty.addListener(LISTENER); }}Copy the code

Like SystemRuleManager, AuthorityRuleManager has a RulePropertyListener handler for rule changes, This RulePropertyListener is an internal class of AuthorityRuleManager, and then there is a configuration class currentProperty that represents the current configuration. When the update rule needs to be loaded, the logic is similar to SystemRuleManager, So no more description.

3.3. AuthoritySlot

AuthoritySlot is the function slot that processes the blacklist and whitelist. When an entry is entered, it calls checkBlackWhiteAuthority() for verification.

public void entry(Context context, ResourceWrapper resourceWrapper, DefaultNode node, int count, boolean prioritized, Object... args) throws Throwable { checkBlackWhiteAuthority(resourceWrapper, context); fireEntry(context, resourceWrapper, node, count, prioritized, args); } /** * Check the whitelist * @param resource * @param context * @throws AuthorityException */ void CheckBlackWhiteAuthority (ResourceWrapper resource, Context Context) throws AuthorityException {// Obtain all rules Map<String, Set<AuthorityRule>> authorityRules = AuthorityRuleManager.getAuthorityRules();if (authorityRules == null) {
        return; } Set<AuthorityRule> rules = authorityrules.get (resource-.getname ());if (rules == null) {
        return;
    }

    for (AuthorityRule rule : rules) {
        if(! AuthorityRuleChecker.passCheck(rule, context)) { throw new AuthorityException(context.getOrigin(), rule); }}}Copy the code

As you can see, this place is for all the black and white list of rules, and then traverse call AuthorityRuleChecker. PassCheck () to check, check the specific logic is simple, is not described here.

4. Flow control

The traffic control principle monitors application traffic indicators, such as QPS or concurrent threads, and controls the traffic when it reaches a specified threshold to avoid being overwhelmed by instantaneous traffic peaks and ensure high availability of applications.

4.1. FlowRule

FlowRule represents a flow control rule and defines various parameters for flow control.

public class FlowRule extends AbstractRule {
    /**
     * The threshold type of flow control (0: thread count, 1: QPS).
     */
    private int grade = RuleConstant.FLOW_GRADE_QPS;

    /**
     * Flow control threshold count.
     */
    private double count;

    /**
     * Flow control strategy based on invocation chain.
     *
     * {@link RuleConstant#STRATEGY_DIRECT} for direct flow control (by origin);
     * {@link RuleConstant#STRATEGY_RELATE} for relevant flow control (with relevant resource);
     * {@link RuleConstant#STRATEGY_CHAIN} for chain flow control (by entrance resource).
     */
    private int strategy = RuleConstant.STRATEGY_DIRECT;

    /**
     * Reference resource in flow control with relevant resource or context.
     */
    private String refResource;

    /**
     * Rate limiter control behavior.
     * 0. default(reject directly), 1. warm up, 2. rate limiter, 3. warm up + rate limiter
     */
    private int controlBehavior = RuleConstant.CONTROL_BEHAVIOR_DEFAULT;

    private int warmUpPeriodSec = 10;

    /**
     * Max queueing time in rate limiter behavior.
     */
    private int maxQueueingTimeMs = 500;

    private boolean clusterMode;
    /**
     * Flow rule config for cluster mode.
     */
    private ClusterFlowConfig clusterConfig;

    /**
     * The traffic shaping (throttling) controller.
     */
    private TrafficShapingController controller;
Copy the code

A traffic limiting rule mainly consists of the following factors, which can be combined to achieve different traffic limiting effects:

  • Resource: indicates the name of the resource, which is the object of the traffic limiting rule
  • Count: traffic limiting threshold
  • Grade: Type of flow limiting threshold (QPS or number of concurrent threads)
  • LimitApp: call source of flow control. If it is default, call source is not differentiated
  • Strategy: Invokes the relational traffic limiting policy
  • ControlBehavior: Flow control effect (direct reject, Warm Up, uniform queuing)

4.2. FlowSlot

FlowSlot is a function slot for flow control. The implementation is as follows:

*/ Private Final FlowRuleChecker checker; public FlowSlot() { this(new FlowRuleChecker()); }... @Override public void entry(Context context, ResourceWrapper resourceWrapper, DefaultNode node, int count, boolean prioritized, Object... args) throws Throwable { checkFlow(resourceWrapper, context, node, count, prioritized); fireEntry(context, resourceWrapper, node, count, prioritized, args); } void checkFlow(ResourceWrapper resource, Context context, DefaultNode node, int count, boolean prioritized) throws BlockException { checker.checkFlow(ruleProvider, resource, context, node, count, prioritized); } private final Function<String, Collection<FlowRule>> ruleProvider = new Function<String, Collection<FlowRule>>() { @Override public Collection<FlowRule> apply(String resource) { // Flow rule map should not be null. Map<String, List<FlowRule>> flowRules = FlowRuleManager.getFlowRuleMap(); return flowRules.get(resource); }}; .Copy the code

A FlowRuleChecker is defined in FlowSLot. The FlowRuleChecker is responsible for checking the flow limiting rules. As you can see, FlowSlot’s actual flow limiting logic is implemented by calling FlowRuleChecker. When you call FlowRuleChecker’s checkFlow() method, you pass in a ruleProvider, which is a Function.

4.3. FlowRuleChecker

FlowRuleChecker checkFlow(); FlowRuleChecker checkFlow();

public void checkFlow(Function<String, Collection<FlowRule>> ruleProvider, ResourceWrapper resource,
                      Context context, DefaultNode node, int count, boolean prioritized) throws BlockException {
    if (ruleProvider == null || resource == null) {
        return;
    }
    Collection<FlowRule> rules = ruleProvider.apply(resource.getName());
    if(rules ! = null) {for (FlowRule rule : rules) {
            if(! canPassCheck(rule, context, node, count, prioritized)) { throw new FlowException(rule.getLimitApp(), rule); }}}}Copy the code

CheckFlow () is a simple way to get a flow limiting rule, and iterate over it by calling canPassCheck(). If the check fails, FlowException is thrown.

public boolean canPassCheck(/*@NonNull*/ FlowRule rule, Context context, DefaultNode node, int acquireCount,
                                boolean prioritized) {
    String limitApp = rule.getLimitApp();
    if (limitApp == null) {
        return true;
    }
    
    if (rule.isClusterMode()) {
        return passClusterCheck(rule, context, node, acquireCount, prioritized);
    }
    
    return passLocalCheck(rule, context, node, acquireCount, prioritized);
}
Copy the code

CanPassCheck () is also simple, calling different methods based on different schemas. Sentinel can be run in cluster mode or local mode, with different flow limiting logic. Because this place does not talk about clusters, so first according to the local model for analysis.

 private static boolean passLocalCheck(FlowRule rule, Context context, DefaultNode node, int acquireCount,
                                      boolean prioritized) {
    Node selectedNode = selectNodeByRequesterAndStrategy(rule, context, node);
    if (selectedNode == null) {
        return true;
    }

    return rule.getRater().canPass(selectedNode, acquireCount, prioritized);
}
Copy the code

In passLocalCheck(), the corresponding Node Node is obtained according to the configured strategy and request source, and then the canPass() method of the corresponding Node is called for verification.

There is a TrafficShapingController in FlowRule, which represents the types of traffic control, including default value, direct reject, Warm Up, and uniform queuing. Therefore, the specific method of limiting traffic depends on the set policy.

4.4. TrafficShapingController

TrafficShapingController is an interface that defines traffic control policies. It has three implementations that represent different processing modes:

  • DefaultController: The default processing policy, rejects processing directly
  • RateLimiterController: Queue at constant speed
  • WarmUpController: WarmUpController or cold startup mode
  • WarmUpRateLimiterController: preheat + in line at a constant speed

FlowRule contains a variable rater of type TrafficShapingController. This rater is created when the rule is updated according to the set rule as follows:

private static TrafficShapingController generateRater(/*@Valid*/ FlowRule rule) {
    if (rule.getGrade() == RuleConstant.FLOW_GRADE_QPS) {
        switch (rule.getControlBehavior()) {
            case RuleConstant.CONTROL_BEHAVIOR_WARM_UP:
                return new WarmUpController(rule.getCount(), rule.getWarmUpPeriodSec(),
                    ColdFactorProperty.coldFactor);
            case RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER:
                return new RateLimiterController(rule.getMaxQueueingTimeMs(), rule.getCount());
            case RuleConstant.CONTROL_BEHAVIOR_WARM_UP_RATE_LIMITER:
                return new WarmUpRateLimiterController(rule.getCount(), rule.getWarmUpPeriodSec(),
                    rule.getMaxQueueingTimeMs(), ColdFactorProperty.coldFactor);
            case RuleConstant.CONTROL_BEHAVIOR_DEFAULT:
            default:
                // Default mode or unknown mode: default traffic shaping controller (fast-reject).
        }
    }
    return new DefaultController(rule.getCount(), rule.getGrade());
}
Copy the code

5. Fuse downgrade

Sentinel fuse degrade can restrict a resource in the call link when it is in unstable state, so that the request can fail quickly and avoid cascading errors caused by affecting other resources. When a resource is degraded, all calls to the resource are automatically disabled in the following degraded time window.

5.1. Downgrade strategy

  • Average response time (DEGRADE_GRADE_RT) : When five requests arrive within 1s and the response time exceeds the threshold of count (ms), the degradability of the response time is reduced to s. Calls to this method will automatically fuse (throw a DegradeException). Pay attention to the Sentinel default statistical RT limit is 4900 ms, is beyond the threshold will be classified as 4900 ms, if need to change this limit by startup configuration items – Dcsp. Sentinel. Statistic. Max. RT = XXX to configure.

  • Abnormal ratio (DEGRADE_GRADE_EXCEPTION_RATIO) : The total number of requests per second is greater than or equal to 5, and the ratio of the total number of exceptions per second to the total number of passes exceeds the threshold for survival. Calls to this method are automatically returned. The threshold range for the abnormal ratio is [0.0, 1.0], representing 0-100%.

  • Number of exceptions (DEGRADE_GRADE_EXCEPTION_COUNT) : When the number of exceptions in the last 1 minute exceeds the threshold, a resource is fused. Notice the statistical timeWindow is minute. If the timeWindow is less than 60 seconds, the circuit breaker may enter the circuit breaker state again after the circuit breaker state ends

5.2. DegradeRule

public class DegradeRule extends AbstractRule { /** * RT threshold or exception ratio threshold count. */ private double  count; /** * Degrade recover timeout (inseconds) when degradation occurs. */ private int timeWindow; /** * Degrade strategy (0: average RT, 1: exception ratio, 2: exception count). */ private int grade = RuleConstant.DEGRADE_GRADE_RT; /** * Minimum number of consecutive slow requests that can trigger RT circuit breaking. ** Maximum number of consecutive slow requests per second @since 1.7.0 */ private int rtSlowRequestAmount = ruleconstant. DEGRADE_DEFAULT_SLOW_REQUEST_AMOUNT; /** * Minimum number of requests per secondinAn active statistic time span) that can trigger circuit breaking. * * @since 1.7.0 */ private int minRequestAmount = RuleConstant.DEGRADE_DEFAULT_MIN_REQUEST_AMOUNT; }Copy the code

DeGradeRule refers to the following rules:

  • Grade: The mode of fuse downgrade, including average response time, abnormal proportion, and abnormal number.
  • Count: indicates the threshold for fusible degradation.
  • TimeWindow: Duration after a fuse downgrade occurred.
  • MinRequestAmount: Minimum threshold for the number of consecutive incoming requests per second for abnormal non-fuse degradation.
  • RtSlowRequestAmount: The number of consecutive incoming requests whose average response time exceeds the threshold per second.

5.3. DegradeSlot

It is very simple to code for a fuse degrade to achieve survival in General Manager.

public void entry(Context context, ResourceWrapper resourceWrapper, DefaultNode node, int count, boolean prioritized, Object... args)
    throws Throwable {
    DegradeRuleManager.checkDegrade(resourceWrapper, context, node, count);
    fireEntry(context, resourceWrapper, node, count, prioritized, args);
}
Copy the code

5.4. DegradeRuleManager

It loads fuse degrade rules and provides fuse degrade verification for call entry.

/** * Save the reversion rule cache, Resource */ Private static final Map<String, Set< assist ule>> Assist erules = new ConcurrentHashMap<>(); /** * Rule change handler */ private static final RulePropertyListener LISTENER = new RulePropertyListener(); private static SentinelProperty<List<DegradeRule>> currentProperty = new DynamicSentinelProperty<>(); static { currentProperty.addListener(LISTENER); }Copy the code

General Manager uses a map to store fuse degrade rules for different asset loads and has its own rule change handler. The load and update logic for rules is similar to that of any other feature slot.

The checkDegrade() method of Entry is called to assist in survival.

 public static void checkDegrade(ResourceWrapper resource, Context context, DefaultNode node, int count)
    throws BlockException {

    Set<DegradeRule> rules = degradeRules.get(resource.getName());
    if (rules == null) {
        return;
    }

    for (DegradeRule rule : rules) {
        if(! rule.passCheck(context, node, count)) { throw new DegradeException(rule.getLimitApp(), rule); }}}Copy the code

The checkDegrade() method obtains a traffic limiting rule based on the resource and then circulates the passCheck() method to check the rule. If the rule fails to pass the check, a DegradeException is thrown.

The checkup logic is provided in passCheck() in the Survival ule as follows:

public boolean passCheck(Context context, DefaultNode node, int acquireCount, Object... Args) {// If it is in a limited window time, directly degradeif (cut.get()) {
        return false; } // Demote only for resource dimensions, regardless of context, regardless of orgin, StatisticSlot accumulates ClusterNodes in defaultNode. ClusterNode clusterNode = ClusterBuilderSlot.getClusterNode(this.getResource());if (clusterNode == null) {
        return true;
    }

    if (grade == RuleConstant.DEGRADE_GRADE_RT) {

        //caseDouble rt = clusterNode.avgrt (); double rt = clusterNode.avgrt (); // The average response time is less than the set thresholdif (rt < this.count) {
            passCount.set(0);
            return true; } // The number of requests increases. If the number of requests is less than 5, the request is passed directlyif (passCount.incrementAndGet() < rtSlowRequestAmount) {
            return true; }}else if (grade == RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO) {

        //caseDouble Exception = ClusterNode.ExceptionQps (); double Exception = ClusterNode.ExceptionQps (); double success = clusterNode.successQps(); double total = clusterNode.totalQps(); // If the total number of requests is less than the set minimum number of requests per second, return directlyif (total < minRequestAmount) {
            return true;
        }
        double realSuccess = success - exception;
        if (realSuccess <= 0 && exception < minRequestAmount) {
            return true;
        }

        if (exception / success < count) {
            return true; }}else if (grade == RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT) {

        //case3: an abnormal number/statistics/total minutes a time window level, if timeWindow time less than 60 s, will fuse in 60 s double exception. = clusterNode totalException (); // If the number of exceptions is less than the specified value, return directlyif (exception < count) {
            return true; }} // Start a scheduled task and execute it after the specified window time. Set the number of requests to 0 and the degrade flag tofalse
    if (cut.compareAndSet(false.true)) {
        ResetTask resetTask = new ResetTask(this);
        pool.schedule(resetTask, timeWindow, TimeUnit.SECONDS);
    }

    return false;
}
Copy the code

PassCheck () is a simple logic, mainly based on the previously obtained data to determine whether the threshold is met, if the threshold is exceeded, return false, and start a thread, its role is to directly degrade the subsequent requests within the specified timeWindow.

6. Summary

This paper mainly analyzes the implementation principle of function slots commonly used in Sentinel, and understands the traffic limiting and degrading strategy of Sentinel.

7. Reference materials

Flow control Fuse degrade system adaptive current limiting blacklist control