美文网首页Sentinel
Sentinel资源节点树构成

Sentinel资源节点树构成

作者: 晴天哥_王志 | 来源:发表于2021-06-13 21:40 被阅读0次

    系列

    相同资源名场景分析

    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。


    相关文章

      网友评论

        本文标题:Sentinel资源节点树构成

        本文链接:https://www.haomeiwen.com/subject/txugeltx.html