Wechat public account: the landlord’s small black road is far away, the future is better learning is boundless, we come on together!
This paper is the first analysis of the Sentinel principle. Due to the short time exposure to this middleware, there may be some understanding bias. I hope we can actively communicate and correct. The main content of the article is mainly read some of the gods of the article, and add their own understanding to write.
The main reference articles are found on Sentinel’s Github at the following address: Reference articles
The main functions of Sentinel are flow control and fuse downgrading. The specific concepts were introduced in the current limiting and fusing section of Dubbo, and will not be described here.
Here’s a quick example of how to use it.
public static void main(String[] args) {
try {
Context context=ContextUtil.enter("context1");
Entry entry=SphU.entry("HelloWorld");
entry.exit();
ContextUtil.exit();
} catch (BlockException ex) {
// Handle flow-controlled logic
System.out.println("blocked!");
}catch (Exception e){
e.printStackTrace();
}
}
Copy the code
try (Entry entry = SphU.entry("HelloWorld")) {
// Your business logic here.
System.out.println("hello world");
} catch (BlockException e) {
// Handle rejected request.
e.printStackTrace();
}
Copy the code
The above are two typical flow control examples. One obvious difference the reader will notice is that the Context class, which is used to represent the Context of a call, does not really matter, as discussed below.
There is also an important class Entry in the example. The parameter HelloWorld can be seen as a resource name, but we need to define some rules before using it. You can define a rule about flow control using the following method:
private void initFlowQpsRule(a) {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule(resourceName);
// set limit qps to 20
rule.setCount(20);
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setLimitApp("default");
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
Copy the code
If no exception is reported when sphu.entry (“HelloWorld”) is called, the business code can be executed. If an error message is displayed, the current conditions are not met and the following service codes are rejected.
Several core concepts
Resource
A resource is a core concept in Sentinel. It can be a service provided by an application, another service invoked by an application, or a piece of code. When a service has a large number of requests and is often overwhelmed by a sudden increase in traffic, resulting in performance degradation or unavailability, we can define a Sentinel resource to adjust the requests through this resource for traffic control and service degradation.
The class that represents a specific resource in Sentinel is a ResourceWrapper.
public abstract class ResourceWrapper {
# resource name
protected final String name;
# Inbound or outbound
protected final EntryType entryType;
# Resource type
protected final int resourceType;
Copy the code
Entry
Entry is a token used in Sentinel to indicate whether or not the stream has passed the limit. If it returns normally, then you can access the sentinel protected backend service. Otherwise, Sentinel will throw a BlockException. In addition, it holds some basic information about the entry() method being executed this time. An Entry is created for each resource invocation.
public abstract class Entry implements AutoCloseable {
# The creation time of the current Entry is mainly used to calculate RT later
private long createTime;
# The node associated with the current Entry. This node records statistics about the resource in the current context
private Node curNode;
The source of the call to the current Entry, usually the application name of the caller
private Node originNode;
private Throwable error;
The resource associated with the current Entry
protected ResourceWrapper resourceWrapper;
Copy the code
class CtEntry extends Entry {
protected Entry parent = null;
protected Entry child = null;
protected ProcessorSlot<Object> chain;
protected Context context;
Copy the code
Maybe it’s a little abstract, but let me draw on someone else’s example, which is very graphic.
From the figure we can see that there is a user-center –> getUserInfo –> getOrderInfo call link. From the code, we know that user-Center is a context name and getUserInfo and getOrderInfo are two resource names.
In the example above, another Entry is called within an Entry, and there is a link. When the sphu.entry () method is called multiple times within a context, a call tree is created, and the nodes of the tree are maintained by parent and child relationships.
Node
Node stores real-time resource statistics, such as passQps, blockQps, and RT.
StatisticNode
StatisticNode
DefaultNode
ClusterNode
DefaultNode
EntranceNode
EntranceNode is an EntranceNode for each context. This node is directly attached to root and is globally unique. Each context has an EntranceNode. DefaultNode records current real-time data. Each DefaultNode is associated with a resource and a ClusterNode. Defaultnodes with the same resources are associated with the same clusterNode.
public interface Node extends OccupySupport.DebugSupport {
long totalRequest(a);
long totalPass(a);
long totalSuccess(a);
Copy the code
public class DefaultNode extends StatisticNode {
private ResourceWrapper id;
private volatile Set<Node> childList = new HashSet<>();
private ClusterNode clusterNode;
Copy the code
Context
public class Context {
// Context name
private final String name;
// The entry node of the current call chain
private DefaultNode entranceNode;
// Call the entry currently being processed in the chain
private Entry curEntry;
// The source of this context (usually representing a different caller, such as a service consumer name or source IP)
private String origin = "";
Copy the code
Context represents the call link Context, through all entries in a call link. Each call to sphu.entry () needs to be executed in a context. If there is no context when there is no current execution, the framework uses the default context, sentinel_default_context.
The Context is stored in a ThreadLocal and is first fetched from ThreadLocal each time it is executed. If the Context is null, then another Context will be created.
When exit is executed on Entry, if the parent of the current Entry is null, it indicates that the current Entry is the topmost node and the Entry of this context has been executed. Therefore, you need to set the context to NULL to clear it from ThreadLocal.
So that’s an important introduction to entity classes.
Sentinel core class analysis Sentinel principle – Entity class Ali Sentinel source code analysis
This article is formatted using MDNICE