sentinel overall workflow

1, ProcessorSlot responsibility chain in Sentinel

In the previous article, we introduced seven kinds of ProcessorSlot in sentinel, which are divided into two categories: one is for data statistics, and the other is for degradation. Sentinel's overall workflow is to use the responsibility chain mode to form a one-way linked list of all processorslots in a certain order to assist in the statistics of resource index data. The ProcessorSlot must be in front of the ProcessorSlot that realizes the degradation function. The reason is very simple. The degradation function needs to be judged according to the index data of resources. Of course, If a ProcessorSlot does not rely on the indicator data to realize the degradation function, the location of the ProcessorSlot is not constrained.

The ProcessorSlotChain that can string ProcessorSlot into a one-way linked list is ProcessorSlotChain. This ProcessorSlotChain is constructed by SlotChainBuilder. By default, the ProcessorSlot registered by the ProcessorSlotChain constructed by SlotChainBuilder and its sequence are 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 is a custom ProcessorSlot, it can be built through AbstractLinkedProcessorSlot

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 entry method of the next ProcessorSlot
            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 exit method of the next ProcessorSlot
            next.exit(context, resourceWrapper, count, args);
        }
    }
}

The ProcessorSlot interface is defined as follows:

public interface ProcessorSlot<T> {
    // Entrance 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: the link context is currently invoked.
  • resourceWrapper: resource ID.
  • param: generic parameter, generally used to pass DefaultNode.
  • Count: Sentinel wraps the resources that need to be protected, which is the same as the implementation of the lock. You need to obtain the lock before you can continue to execute. The function of count is the same as that of the tryAcquire method in concurrent programming AQS. Count indicates the number of shared resources occupied by the application. The execution can continue only when enough shared resources are applied. For example, the thread pool has 200 threads, and the current method execution needs to apply for 3 threads to execute, so the count is 3. The value of count is generally 1. When the current limit threshold type configured by the current limit rule is threads, it means that a thread needs to be applied for. When the current limit threshold type configured by the current limit rule is qps, it means that a 1 token needs to be applied for (assuming that the token bucket algorithm is used).
  • Prioritized: indicates whether the request is prioritized. The value passed by SphU#entry is false.
  • args: the parameter passed by the calling method, which is used to limit the current of hotspot parameters.

2, Sentinel overall workflow

1. Do not use the adapter example provided by Sentinel

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));
     // Business execution method
       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 consists of five steps:

  1. Call the ContextUtil#enter method. Responsible for creating Context for the current call link, creating it and storing it into ThreadLocal, and creating EntranceNode for Conetxt.
  2. Call the SphU#entry method. The core call in the overall link here is that CtSph is responsible for creating ResourceWrapper objects for resources, constructing a global unique ProcessorSlotChain for resources, creating CtEntry for resources, and assigning CtEntry to Context. of the current call link. CurEntry and finally call the ProcessorSlotChain#entry method to complete the entry method invocation of a one-way linked list.
  3. If an exception is thrown and the exception type is not BlockException, the Tracer#trace method is called to record the exception, which is the DefaultNode auto increment constant of the current resource
  4. Call the Entry#exit method;
  5. Call the ContextUtil#exit method.

Reference article:
06 responsibility chain model in sentinel and Sentinel's overall workflow

Keywords: Java sentinel

Added by access9 on Sun, 13 Feb 2022 07:09:23 +0200