One , Sentinel Inside ProcessorSlot Responsibility chain
In the last article, we introduced Sentinel Seven kinds in ProcessorSlot, They fall into two categories , One is data statistics , One is to realize the degradation function .Sentinel The overall workflow is to use the responsibility chain model to integrate all ProcessorSlot Form a one-way linked list in a certain order to assist in the statistics of resource index data ProcessorSlot Must be in the realization of the degradation function ProcessorSlot In front of , The reason is simple , The degradation function needs to be judged according to the indicator data of resources , Of course , If a ProcessorSlot Do not rely on index data to realize the degradation function , So this one ProcessorSlot There is no constraint on the position of .
The implementation will ProcessorSlot String into a one-way linked list is ProcessorSlotChain, This ProcessorSlotChain By SlotChainBuilder Tectonic , Default SlotChainBuilder Tectonic ProcessorSlotChain Registered ProcessorSlot And the sequence is shown in the following code .
public class DefaultSlotChainBuilder implements SlotChainBuilder {
@Override
public ProcessorSlotChain build() {
ProcessorSlotChain chain = new DefaultProcessorSlotChain();
chain.addLast(new NodeSelectorSlot());
chain.addLast(new ClusterBuilderSlot());
chain.addLast(new LogSlot());
chain.addLast(new StatisticSlot());
chain.addLast(new AuthoritySlot());
chain.addLast(new SystemSlot());
chain.addLast(new FlowSlot());
chain.addLast(new DegradeSlot());
return chain;
}
}
If it's custom ProcessorSlot Can pass AbstractLinkedProcessorSlot Build
public abstract class AbstractLinkedProcessorSlot<T> implements ProcessorSlot<T> {
// The next node of the current node
private AbstractLinkedProcessorSlot<?> next = null;
public void setNext(AbstractLinkedProcessorSlot<?> next) {
this.next = next;
}
@Override
public void fireEntry(Context context, ResourceWrapper resourceWrapper, Object obj, int count, boolean prioritized, Object... args)
throws Throwable {
if (next != null) {
T t = (T) obj;
// Call the next ProcessorSlot Of entry Method
next.entry(context,resourceWrapper,t,count,prioritized,args);
}
}
@Override
public void fireExit(Context context, ResourceWrapper resourceWrapper, int count, Object... args) {
if (next != null) {
// Call the next ProcessorSlot Of exit Method
next.exit(context, resourceWrapper, count, args);
}
}
}
ProcessorSlot The interface is defined as follows :
public interface ProcessorSlot<T> {
// Entry method
void entry(Context context, ResourceWrapper resourceWrapper, T param, int count, boolean prioritized,Object... args) throws Throwable;
// Call the next ProcessorSlot#entry Method
void fireEntry(Context context, ResourceWrapper resourceWrapper, Object obj, int count, boolean prioritized,Object... args) throws Throwable;
// Export method
void exit(Context context, ResourceWrapper resourceWrapper, int count, Object... args);
// Call the next ProcessorSlot#exit Method
void fireExit(Context context, ResourceWrapper resourceWrapper, int count, Object... args);
}
Main method parameters :
- context: Current call link context .
- resourceWrapper: resources ID.
- param: The generic parameter , Generally used to transmit DefaultNode.
- count:Sentinel Package the resources that need to be protected , This is the same as the implementation of locks , You need to acquire the lock before proceeding . and count And concurrent programming AQS in tryAcquire Method parameters work the same ,count Indicates the number of shared resources occupied by the application , Only when enough shared resources are applied for can the execution continue . for example , Thread pool has 200 Threads , The current method requires application 3 Threads can execute , that count Namely 3.count The value of is usually 1, When the current limit threshold configured by the current limit rule is threads when , Indicates that you need to apply for a thread , When the current limit threshold configured by the current limit rule is qps when , Indicates that you need to apply 1 token ( Suppose you use the token bucket algorithm ).
- prioritized: Indicates whether to prioritize requests ,SphU#entry The value passed is false.
- args: Call the parameters passed by the method , It is used to realize hot spot parameter current limiting .
Two ,Sentinel The overall workflow
1, Don't use Sentinel Provided adapter example
ContextUtil.enter(" Context name , for example :sentinel_spring_web_context");
Entry entry = null;
try {
entry = SphU.entry(" Resource name , for example :/rpc/openfein/demo", EntryType.IN ( perhaps EntryType.OUT));
// Execute business methods
return doBusiness();
} catch (Exception e) {
if (!(e instanceof BlockException)) {
Tracer.trace(e);
}
throw e;
} finally {
if (entry != null) {
entry.exit(1);
}
ContextUtil.exit();
}
The process for 5 Step :
- call ContextUtil#enter Method . Responsible for creating Context, Save after creation ThreadLocal, As well as Conetxt establish EntranceNode
- call SphU#entry Method . Here is the core call in the overall link ,CtSph Responsible for creating ResourceWrapper Object and construct a globally unique ProcessorSlotChain、 Create for resources CtEntry And will CtEntry Assigned to the current call link Context.curEntry、 Last call ProcessorSlotChain#entry Method to complete a one-way linked list entry Method call .
- If an exception is thrown , And the exception type is not BlockException abnormal , Call Tracer#trace Method record exception , For the current resource DefaultNode Autoincrement constant
- call Entry#exit Method ;
- call ContextUtil#exit Method .
Reference article :
06 Sentinel The responsibility chain model in Sentinel The overall workflow of