setinel源码分析一

207 阅读2分钟

setinel源码

内容:详解SphU.entry(KEY)调用过程。主要两个步骤,构造调用链,然后执行调用链。

由官网示例程序FlowQpsDemo类进入。

// 由此进入判断是否拿到令牌
entry = SphU.entry(KEY); 
//Env.sph为CtSph(),触发初始化,这个方法有其他的重载方法,比如param为Method
public static Entry entry(String name) throws BlockException {
    return Env.sph.entry(name, EntryType.OUT, 1, OBJECTS0);
}
//CtSph()#entry,new一个默认资源
@Override
public Entry entry(String name, EntryType type, int count, Object... args) throws BlockException {
    StringResourceWrapper resource = new StringResourceWrapper(name, type);
    return entry(resource, count, args);
}
//次数prioritized是啥用?
private Entry entryWithPriority(ResourceWrapper resourceWrapper, int count, boolean prioritized, Object... args)
    throws BlockException {
    Context context = ContextUtil.getContext();
    if (context instanceof NullContext) {
        return new CtEntry(resourceWrapper, null, context);
    }

    if (context == null) {
        //如果没有Context这里会默认给一个名sentinel_default_context
        context = InternalContextUtil.internalEnter(Constants.CONTEXT_DEFAULT_NAME);
    }

    // 判断是否开启全局开关
    if (!Constants.ON) {
        return new CtEntry(resourceWrapper, null, context);
    }

    //关键代码,这里构建一个SlotChain
    ProcessorSlot<Object> chain = lookProcessChain(resourceWrapper);

    /*
     * Means amount of resources (slot chain) exceeds {@link Constants.MAX_SLOT_CHAIN_SIZE},
     * so no rule checking will be done.
     */
    if (chain == null) {
        return new CtEntry(resourceWrapper, null, context);
    }

    Entry e = new CtEntry(resourceWrapper, chain, context);
    try {
        // chain为DefaultProcessorSlotChain
        chain.entry(context, resourceWrapper, null, count, prioritized, args);
    } catch (BlockException e1) {
        e.exit(count, args);
        throw e1;
    } catch (Throwable e1) {
        // This should not happen, unless there are errors existing in Sentinel internal.
        RecordLog.info("Sentinel unexpected exception", e1);
    }
    return e;
}

lookProcessChain相关

// 采用双重检查缩的方式构建一个SlotChain
public ProcessorSlot<Object> lookProcessChain(ResourceWrapper resourceWrapper) {
    ProcessorSlotChain chain = chainMap.get(resourceWrapper);
    if (chain == null) {
        synchronized (LOCK) {
            chain = chainMap.get(resourceWrapper);
            if (chain == null) {
                // Entry size limit.
                if (chainMap.size() >= Constants.MAX_SLOT_CHAIN_SIZE) {
                    return null;
                }
                // 组建一个新的Slot链
                chain = SlotChainProvider.newSlotChain();
                // key为ResourceWrapper,说明不同的资源名对应一个Chain,因此不同的contextName可能对应同一个资源,因此可能对应一个Chain
                Map<ResourceWrapper, ProcessorSlotChain> newMap = new HashMap<ResourceWrapper, ProcessorSlotChain>(
                    chainMap.size() + 1);
                newMap.putAll(chainMap);
                newMap.put(resourceWrapper, chain);
                chainMap = newMap;
            }
        }
    }
    return chain;
}
@Spi(isDefault = true)
public class DefaultSlotChainBuilder implements SlotChainBuilder {

    @Override
    public ProcessorSlotChain build() {
    //该类为chain的承载容器,成员有head,endAbstractLinkedProcessorSlot<?>),head和end是一个链式结构,串起来。
        ProcessorSlotChain chain = new DefaultProcessorSlotChain();

        //load所有的Slot,下边有介绍
        List<ProcessorSlot> sortedSlotList = SpiLoader.of(ProcessorSlot.class).loadInstanceListSorted();
        // 设置ProcessorSlotChain里边的head,end,将Slot按照顺序串起来。一共是8SlotNodeSelectorSlot,ClusterBuilerSlot,LogSlot,StatisticSlot,AuthoritySlot,SystemSlot,FlowSlot,DegradeSlot
        for (ProcessorSlot slot : sortedSlotList) {
            if (!(slot instanceof AbstractLinkedProcessorSlot)) {
                RecordLog.warn("The ProcessorSlot(" + slot.getClass().getCanonicalName() + ") is not an instance of AbstractLinkedProcessorSlot, can't be added into ProcessorSlotChain");
                continue;
            }

            chain.addLast((AbstractLinkedProcessorSlot<?>) slot);
        }

        return chain;
    }
}
public List<S> loadInstanceListSorted() {
    // 通过ClassLoader加载出来ProcessorSlot所有的实现
    load();
    // 创造类实例
    return createInstanceList(sortedClassList);
}

chain.entry相关

// DefaultProcessorSlotChain#entry方法,由first进入
@Override
public void entry(Context context, ResourceWrapper resourceWrapper, Object t, int count, boolean prioritized, Object... args)
    throws Throwable {
    first.transformEntry(context, resourceWrapper, t, count, prioritized, args);
}
AbstractLinkedProcessorSlot<?> first = new AbstractLinkedProcessorSlot<Object>() {

    @Override
    public void entry(Context context, ResourceWrapper resourceWrapper, Object t, int count, boolean prioritized, Object... args)
        throws Throwable {
        super.fireEntry(context, resourceWrapper, t, count, prioritized, args);
    }

    @Override
    public void exit(Context context, ResourceWrapper resourceWrapper, int count, Object... args) {
        super.fireExit(context, resourceWrapper, count, args);
    }

};
// AbstractLinkedProcessorSlot #fireEntry的next一步一步进入各个Slot调用transformEntry
@Override
public void fireEntry(Context context, ResourceWrapper resourceWrapper, Object obj, int count, boolean prioritized, Object... args)
    throws Throwable {
    if (next != null) {
        next.transformEntry(context, resourceWrapper, obj, count, prioritized, args);
    }
}

未完待续

接下来继续探索FlowSlot以及DegradeSlot内部逻辑