• Sentinel-NodeSelectorSlot


    NodeSelectorSlot解析

    在理解这一章前,可以先阅读sentinel整体架构可能了解起来更有帮助。

    在NodeSelectorSlot中维护这变量  private volatile Map<String, DefaultNode> map = new HashMap<String, DefaultNode>(10);

    相同资源共享一个chain,也就使用同一个NodeSelectorSlot对象。其中key表示context name 而value表示DefaultNode,说明对于相同的资源名称的不同contextName中各自有一个defaultNode,并添加到数结构中。

    代码如下:

        @Override
        public void entry(Context context, ResourceWrapper resourceWrapper, Object obj, int count, boolean prioritized, Object... args)
            throws Throwable {
            /*
             * It's interesting that we use context name rather resource name as the map key.
             *
             * Remember that same resource({@link ResourceWrapper#equals(Object)}) will share
             * the same {@link ProcessorSlotChain} globally, no matter in which context. So if
             * code goes into {@link #entry(Context, ResourceWrapper, DefaultNode, int, Object...)},
             * the resource name must be same but context name may not.
             *
             * If we use {@link com.alibaba.csp.sentinel.SphU#entry(String resource)} to
             * enter same resource in different context, using context name as map key can
             * distinguish the same resource. In this case, multiple {@link DefaultNode}s will be created
             * of the same resource name, for every distinct context (different context name) each.
             *
             * Consider another question. One resource may have multiple {@link DefaultNode},
             * so what is the fastest way to get total statistics of the same resource?
             * The answer is all {@link DefaultNode}s with same resource name share one
             * {@link ClusterNode}. See {@link ClusterBuilderSlot} for detail.
             */
            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;
                        // Build invocation tree
                        // 这边会继续构建调用树
                        /**
                         * 相同资源的DefaultNode 不同context name的 都会添加到对应的entranceNode上,
                         * 如果context name相同  资源名称也相同   则  DefaultNode在多线程内共享
                         */
                        ((DefaultNode)context.getLastNode()).addChild(node);
                    }
    
                }
            }
    
            // 设置context的当前node为当前资源的的defaultNode
            context.setCurNode(node);
            // 触发下一个slot
            fireEntry(context, resourceWrapper, node, count, prioritized, args);
        }
  • 相关阅读:
    Pytest(2)使用和调用方法
    lnmp一键搭建环境 running
    cd / 、cd~、cd .和cd..区别 running
    php算法之冒泡排序 running
    linux系统安装 running
    webpack之urlloader running
    Unix系列shell程序编写(下)
    目标文件格式分析工具: ar,nm,objdump,objcopy,readelf
    Unix系列shell程序编写(上)
    在vmware下安装的linux系统上添加eth1
  • 原文地址:https://www.cnblogs.com/gaojy/p/15291184.html
Copyright © 2020-2023  润新知