Sentinel core process source code analysis

Sentinel's processing slot (ProcessorSlot)

It can be said that the various functions implemented by sentinel are completed by each processing slot. ProcessorSlot defines four methods:

This method is triggered when the processing slot is entered.

This method is triggered after processing the entry method

This method is triggered when exiting the processing slot

This method is triggered when the exit method is completed.

 Sentinel's core processing slot

 Among them: FlowSlot is the processing slot for processing flow control rules, and DegradeSlot is the processing slot for processing downgrade rules. . . . and so on

Sentinel's processing slot chain---DefaultProcessorSlotChain

 
 

From the DefaultProcessorSlotChain class inheritance diagram and constructor, DefaultProcessorSlotChain uses the decorator mode to internally construct a one-way linked list of AbstractLinkedProcessorSlot

At the same time, looking at the relevant code of AbstractLinkedProcessorSlot, you can find:

 AbstractLinkedProcessorSlot implements two fire methods, both of which trigger related actions of the next node (Slot) associated with itself.

The above is the core source code knowledge reserve about the core process of sentinel. With the above foundation, we start the core process source code analysis. Please remember: The various functions of sentinel are completed by various slots. DefaultProcessorSlotChain is composed of AbstractLinkedProcessorSlot In the single-linked list, the two fire methods of AbstractLinkednProcessorSlot trigger the corresponding method call of the next slot associated with itself.

Sentinel's data loading container Node

Take a look at sentinel’s Node class inheritance diagram:

 Node has only one direct subclass: StatisticNode. All other nodes are direct or indirect subclasses of StatisticNode.

Node defines various interface methods for data statistics:

 The highlight: StatisticNode

First look at the class attributes:

There are two key ArrayMetrics in StatisticNode, which are the key to data statistics.

The screenshot of ArrayMetric's properties is as follows:

 ArrayMetric has a key attribute

LeapArray<MetricBucket> data = new OccupiableBucketLeapArray(sampleCount, intervalInMs);

This was specifically analyzed in the previous article about the implementation principle of sentinel---sliding window_Yuchen Xingguang's blog-CSDN blog .

So so far it can be understood like this:

The StatisticNode object contains attributes: ArrayMetric, and the ArrayMetric object contains: LeapArray<MetricBucket> object, that is to say: StatisticNode can complete data collection through the sliding window data statistics feature of LeapArray, and then complete the data statistics function.

Start with a simple piece of code

The above code is the simplest demo of sentinel implementing current limiting. Source code analysis starts here:

Class inheritance diagram of FlowRule:

 Properties defined by FlowRule:

private int grade = RuleConstant.FLOW_GRADE_QPS; // Current limit type, the default is QPS private double count; // Current limit threshold
private int strategy = RuleConstant.STRATEGY_DIRECT; // The default current limit strategy is to throw an exception directly

The above are several key attributes

What operations does FlowRuleManager#loadRules do?

 From the class source code, FlowManager defines a Map, which stores the mapping between resource names and FlowRule lists.

There is also a FlowPropertyListener flow control rule listener

There is also a SentinelProperty object, and a listener FlowPropertyListener is added to the SentinelProperty object

SentinelProperty is a subclass of DynamicSentinelProperty. The DynamicSentinelProperty object will call the listener object when the property changes.

so:

When FlowManager#loadRules,

 DynamicSentinelProperty#updateValue will be called

 Finally, the ConfigUpdate method of FlowPropertyListener will be called to complete the loading of the rules.

 At this point: flowRules will construct a mapping map between the resource name and the list of flow limiting rules.

SphU.entry("AddUser") source code tracking

 SphU#entry calls Env.sph.entry

 It is equivalent to the final function being completed by CtSph#entry. Of course, there is also a static code block. The function completed by the static code block will be revealed later! continue down

The code is traced all the way and finally reaches: CtSph#entryWithPriority method:

 
 

 From the entryWithPriority method:

1 First construct a Context context

2 Build a processing tank chain

3 Enter the processing slot chain processing logic

Let’s look at the core logic first: building a processing slot chain

Complete the generation of processing slot chain through SlotChainProvider#newSlotChain, and then put it into a map

SlotChainProvider#newSlotChain

 Here, the loading of the default SlotChainBuilder is completed through the SPI mechanism of sentinel. By default, an instance of DefaultSlotChainBuilder is returned. Eventually, DefaultSlotChainBuilder#build will be called to build a DefaultProcessorSlotChain and returned. As mentioned in the previous basic knowledge reserve, DefaultProcessorSlotChain contains a single item of AbstractLinkedProcessSlot. Linked list is the core basis for various subsequent functions of sentinel.

 

Through debugging, it was found that through the SPI mechanism, the Slots of each function are instantiated to form a single necklace list.

 At this point, the mainstream core logic of sentinel has basically been analyzed.

That is: through the SPI mechanism, the SLots of each function are constructed into a one-way linked list. When making subsequent requests, the respective rules will be judged through the linked list in turn. If the corresponding rule is triggered, a BlockException will be thrown.

 Among them: FlowException, DegradeException, AuthorityException, SystemBlockException are all subclasses of BlockException.

Source code analysis of core functions of each Slot

FlowSlot: Flow control rule processing slot

 Whether the current limit is determined is entrusted to checker#checkFlow.

The final traffic limiting logic is determined by: TrafficShapingController#canPass

 This TrafficShapingController is a property in FlowRule. When building the resource and rule list through FlowRuleManager, it was mentioned that the DefaultController class was created by default.

Check out the DefaultController#canPass method

 From the code logic point of view, the core calculation is calculated by the method avgUsedTokens(node), and this method takes the existing data in the node? So where does the node data come from? Tracking all the way, a slot linked list will be built in the previous DefaultProcessorSlotChain, including a StatisticSlot. This slot is dedicated to data statistics. Take a look at StatisticSlot.

code:

 StatisticSlot is a slot about statistics. It first triggers subsequent slot calls. If it can successfully return to this method, it means that the subsequent processing does not throw an exception, and the success number and total number are +count. If during the subsequent slot processing If an exception is thrown, it will be captured by the slot, and different logical processing will be done according to the captured exception.

 At this point, it seems that the implementation logic of sentinel current limiting, downgrading, circuit breaker and other functions has been completely sorted out. but:

I have a question: Whether it is current limiting or downgrade fuses, etc., statistics are collected within a period of time, and StatisticSlot counts by adding data to nodes. How are nodes and time units connected? In other words: How does the node in StatisticSlot count the data according to the unit time, and the subsequent code also obtains the data within the time unit when fetching the data ?

When talking about DefaultProcessorSlotChain above, some details were ignored. Through debugging, we found that the order of the constructed one-way linked list of DefaultProcessorSlotChain is:

1 NodeSelectorSlot   2 ClusterBuilderSlot  3 StatisticSlot  4 AuthoritySlot 

5 SystemSlot  6 FlowSlot  7 DegradeSlot 

The tracking code calls the logic and counts the passing data through node.pass() in StatisticSlot. The Node here is ClusterNode, and ClusterNode is a direct subclass of StatisticNode. It is mentioned in the basic knowledge reserve above: StatisticNode completes sliding window statistics through the attribute ArrayMetric->LeapArray. In other words: StatisticSlot completes sliding window statistics through StatisticNode, including: passing data, abnormal data, total data, etc.

At this point: the complete calling link of the flow control rules, the logic has been completely sorted out.

Sentinel assembles all slots into a single linked list by building DefaultProcessorSlotChain. The linked list sequence is:

NodeSelectorSlot --》ClusterBuilderSlot -》StatisticSlot -》AuthoritySlot 

-》SystemSlot-》FlowSlot-》DegradeSlot

The current limiting logic is processed in FlowSlot. The current limiting is completed through the StatisticNode in the Slot to perform sliding window counting statistics. And the count statistics happens in StatisticSlot 

The above is the core process of Sentinel that has been sorted out by analyzing the current limiting rules. In this process, there are still many details that have not been paid attention to.

If interested students can track the processing process of DegradSlot by themselves to complete the processing logic of the degradation rules.

Guess you like

Origin blog.csdn.net/qq_39203337/article/details/132168575