系列
- Sentinel流程介绍
- Sentinel资源节点树构成
- Sentinel滑动窗口介绍
- Sentinel流量控制
- Sentinel的职责链slot介绍
- Sentinel熔断降级
- Sentinel Dashboard和应用通信
- Sentinel 控制台
相同资源名场景分析
Entry entry = null;
try {
entry = SphU.entry("abc");
entry = SphU.entry("abc");
} catch (BlockException e1) {
} finally {
if (entry != null) {
entry.exit();
}
}
创建Context
public class ContextUtil {
protected static Context trueEnter(String name, String origin) {
Context context = contextHolder.get();
if (context == null) {
Map<String, DefaultNode> localCacheNameMap = contextNameNodeMap;
DefaultNode node = localCacheNameMap.get(name);
if (node == null) {
if (localCacheNameMap.size() > Constants.MAX_CONTEXT_NAME_SIZE) {
setNullContext();
return NULL_CONTEXT;
} else {
LOCK.lock();
try {
node = contextNameNodeMap.get(name);
if (node == null) {
if (contextNameNodeMap.size() > Constants.MAX_CONTEXT_NAME_SIZE) {
setNullContext();
return NULL_CONTEXT;
} else {
node = new EntranceNode(new StringResourceWrapper(name, EntryType.IN), null);
// Add entrance node.
Constants.ROOT.addChild(node);
Map<String, DefaultNode> newMap = new HashMap<>(contextNameNodeMap.size() + 1);
newMap.putAll(contextNameNodeMap);
newMap.put(name, node);
contextNameNodeMap = newMap;
}
}
} finally {
LOCK.unlock();
}
}
}
// 这里的node设置的是Context的EntranceNode
context = new Context(node, name);
context.setOrigin(origin);
contextHolder.set(context);
}
return context;
}
}
- 首先在ThreadLocal获取,获取不到就创建,不然就返回
- 然后再Map中根据ContextName找一个Node
- 没有找到Node就加锁的方式,创建一个EntranceNode,然后放入Map中
- 创建Context,设置node,name,origin,再放入ThreadLocal中
第一次创建Entry
Entry e = new CtEntry(resourceWrapper, chain, context);
class CtEntry extends Entry {
protected Entry parent = null;
protected Entry child = null;
protected ProcessorSlot<Object> chain;
protected Context context;
protected LinkedList<BiConsumer<Context, Entry>> exitHandlers;
CtEntry(ResourceWrapper resourceWrapper, ProcessorSlot<Object> chain, Context context) {
super(resourceWrapper);
this.chain = chain;
this.context = context;
setUpEntryFor(context);
}
private void setUpEntryFor(Context context) {
// The entry should not be associated to NullContext.
if (context instanceof NullContext) {
return;
}
// 首次返回为null
this.parent = context.getCurEntry();
if (parent != null) {
((CtEntry) parent).child = this;
}
// 设置Context的curEntry为当前的CtEntry
context.setCurEntry(this);
}
}
第一次执行NodeSelectorSlot
@Spi(isSingleton = false, order = Constants.ORDER_NODE_SELECTOR_SLOT)
public class NodeSelectorSlot extends AbstractLinkedProcessorSlot<Object> {
private volatile Map<String, DefaultNode> map = new HashMap<String, DefaultNode>(10);
@Override
public void entry(Context context, ResourceWrapper resourceWrapper, Object obj, int count, boolean prioritized, Object... args)
throws Throwable {
DefaultNode node = map.get(context.getName());
if (node == null) {
synchronized (this) {
node = map.get(context.getName());
if (node == null) {
node = new DefaultNode(resourceWrapper, null);
HashMap<String, DefaultNode> cacheMap = new HashMap<String, DefaultNode>(map.size());
cacheMap.putAll(map);
cacheMap.put(context.getName(), node);
map = cacheMap;
// 构建调用树,添加entranceNode的子节点
((DefaultNode) context.getLastNode()).addChild(node);
}
}
}
// 设置Context的当前节点
context.setCurNode(node);
fireEntry(context, resourceWrapper, node, count, prioritized, args);
}
}
public class Context {
private final String name;
private DefaultNode entranceNode;
private Entry curEntry;
private String origin = "";
private final boolean async;
public Node getLastNode() {
if (curEntry != null && curEntry.getLastNode() != null) {
return curEntry.getLastNode();
} else {
return entranceNode;
}
}
public Context setCurNode(Node node) {
this.curEntry.setCurNode(node);
return this;
}
}
第二次创建Entry
Entry e = new CtEntry(resourceWrapper, chain, context);
class CtEntry extends Entry {
protected Entry parent = null;
protected Entry child = null;
protected ProcessorSlot<Object> chain;
protected Context context;
protected LinkedList<BiConsumer<Context, Entry>> exitHandlers;
CtEntry(ResourceWrapper resourceWrapper, ProcessorSlot<Object> chain, Context context) {
super(resourceWrapper);
this.chain = chain;
this.context = context;
setUpEntryFor(context);
}
private void setUpEntryFor(Context context) {
// The entry should not be associated to NullContext.
if (context instanceof NullContext) {
return;
}
// 首次返回为null
this.parent = context.getCurEntry();
if (parent != null) {
((CtEntry) parent).child = this;
}
// 设置Context的curEntry为当前的CtEntry
context.setCurEntry(this);
}
}
第二次执行NodeSelectorSlot
@Spi(isSingleton = false, order = Constants.ORDER_NODE_SELECTOR_SLOT)
public class NodeSelectorSlot extends AbstractLinkedProcessorSlot<Object> {
private volatile Map<String, DefaultNode> map = new HashMap<String, DefaultNode>(10);
@Override
public void entry(Context context, ResourceWrapper resourceWrapper, Object obj, int count, boolean prioritized, Object... args)
throws Throwable {
DefaultNode node = map.get(context.getName());
if (node == null) {
synchronized (this) {
node = map.get(context.getName());
if (node == null) {
node = new DefaultNode(resourceWrapper, null);
HashMap<String, DefaultNode> cacheMap = new HashMap<String, DefaultNode>(map.size());
cacheMap.putAll(map);
cacheMap.put(context.getName(), node);
map = cacheMap;
// 构建调用树,添加entranceNode的子节点
((DefaultNode) context.getLastNode()).addChild(node);
}
}
}
// 设置Context的当前节点
context.setCurNode(node);
fireEntry(context, resourceWrapper, node, count, prioritized, args);
}
}
public class Context {
private final String name;
private DefaultNode entranceNode;
private Entry curEntry;
private String origin = "";
private final boolean async;
public Node getLastNode() {
if (curEntry != null && curEntry.getLastNode() != null) {
return curEntry.getLastNode();
} else {
return entranceNode;
}
}
public Context setCurNode(Node node) {
this.curEntry.setCurNode(node);
return this;
}
}
不同资源名场景分析
Entry entry = null;
try {
entry = SphU.entry("abc");
entry = SphU.entry("abcd");
} catch (BlockException e1) {
} finally {
if (entry != null) {
entry.exit();
}
}
第一次创建Entry
Entry e = new CtEntry(resourceWrapper, chain, context);
class CtEntry extends Entry {
protected Entry parent = null;
protected Entry child = null;
protected ProcessorSlot<Object> chain;
protected Context context;
protected LinkedList<BiConsumer<Context, Entry>> exitHandlers;
CtEntry(ResourceWrapper resourceWrapper, ProcessorSlot<Object> chain, Context context) {
super(resourceWrapper);
this.chain = chain;
this.context = context;
setUpEntryFor(context);
}
private void setUpEntryFor(Context context) {
// The entry should not be associated to NullContext.
if (context instanceof NullContext) {
return;
}
// 首次返回为null
this.parent = context.getCurEntry();
if (parent != null) {
((CtEntry) parent).child = this;
}
// 设置Context的curEntry为当前的CtEntry
context.setCurEntry(this);
}
}
第一次执行NodeSelectorSlot
@Spi(isSingleton = false, order = Constants.ORDER_NODE_SELECTOR_SLOT)
public class NodeSelectorSlot extends AbstractLinkedProcessorSlot<Object> {
private volatile Map<String, DefaultNode> map = new HashMap<String, DefaultNode>(10);
@Override
public void entry(Context context, ResourceWrapper resourceWrapper, Object obj, int count, boolean prioritized, Object... args)
throws Throwable {
DefaultNode node = map.get(context.getName());
if (node == null) {
synchronized (this) {
node = map.get(context.getName());
if (node == null) {
node = new DefaultNode(resourceWrapper, null);
HashMap<String, DefaultNode> cacheMap = new HashMap<String, DefaultNode>(map.size());
cacheMap.putAll(map);
cacheMap.put(context.getName(), node);
map = cacheMap;
// 构建调用树,添加entranceNode的子节点
((DefaultNode) context.getLastNode()).addChild(node);
}
}
}
// 设置Context的当前节点
context.setCurNode(node);
fireEntry(context, resourceWrapper, node, count, prioritized, args);
}
}
public class Context {
private final String name;
private DefaultNode entranceNode;
private Entry curEntry;
private String origin = "";
private final boolean async;
public Node getLastNode() {
if (curEntry != null && curEntry.getLastNode() != null) {
return curEntry.getLastNode();
} else {
return entranceNode;
}
}
public Context setCurNode(Node node) {
this.curEntry.setCurNode(node);
return this;
}
}
第二次创建Entry
Entry e = new CtEntry(resourceWrapper, chain, context);
class CtEntry extends Entry {
protected Entry parent = null;
protected Entry child = null;
protected ProcessorSlot<Object> chain;
protected Context context;
protected LinkedList<BiConsumer<Context, Entry>> exitHandlers;
CtEntry(ResourceWrapper resourceWrapper, ProcessorSlot<Object> chain, Context context) {
super(resourceWrapper);
this.chain = chain;
this.context = context;
setUpEntryFor(context);
}
private void setUpEntryFor(Context context) {
// The entry should not be associated to NullContext.
if (context instanceof NullContext) {
return;
}
// 首次返回为null
this.parent = context.getCurEntry();
if (parent != null) {
((CtEntry) parent).child = this;
}
// 设置Context的curEntry为当前的CtEntry
context.setCurEntry(this);
}
}
第二次执行NodeSelectorSlot
@Spi(isSingleton = false, order = Constants.ORDER_NODE_SELECTOR_SLOT)
public class NodeSelectorSlot extends AbstractLinkedProcessorSlot<Object> {
private volatile Map<String, DefaultNode> map = new HashMap<String, DefaultNode>(10);
@Override
public void entry(Context context, ResourceWrapper resourceWrapper, Object obj, int count, boolean prioritized, Object... args)
throws Throwable {
DefaultNode node = map.get(context.getName());
if (node == null) {
synchronized (this) {
node = map.get(context.getName());
if (node == null) {
node = new DefaultNode(resourceWrapper, null);
HashMap<String, DefaultNode> cacheMap = new HashMap<String, DefaultNode>(map.size());
cacheMap.putAll(map);
cacheMap.put(context.getName(), node);
map = cacheMap;
// 构建调用树,第一次添加entranceNode的子节点
// 第二次添加到当前节点的父节点当中
((DefaultNode) context.getLastNode()).addChild(node);
}
}
}
// 设置Context的当前节点
context.setCurNode(node);
fireEntry(context, resourceWrapper, node, count, prioritized, args);
}
}
public class Context {
private final String name;
private DefaultNode entranceNode;
private Entry curEntry;
private String origin = "";
private final boolean async;
public Node getLastNode() {
if (curEntry != null && curEntry.getLastNode() != null) {
return curEntry.getLastNode();
} else {
return entranceNode;
}
}
public Context setCurNode(Node node) {
this.curEntry.setCurNode(node);
return this;
}
}
class CtEntry extends Entry {
protected Entry parent = null;
protected Entry child = null;
@Override
public Node getLastNode() {
return parent == null ? null : parent.getCurNode();
}
}
-
因为资源名不同所以对应的职责链条,因此NodeSelectorSlot会重新创建DefaultNode。
网友评论