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,end(AbstractLinkedProcessorSlot<?>),head和end是一个链式结构,串起来。
ProcessorSlotChain chain = new DefaultProcessorSlotChain();
//load所有的Slot,下边有介绍
List<ProcessorSlot> sortedSlotList = SpiLoader.of(ProcessorSlot.class).loadInstanceListSorted();
// 设置ProcessorSlotChain里边的head,end,将Slot按照顺序串起来。一共是8个Slot:NodeSelectorSlot,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内部逻辑