Dubbo集群之Directory模块

293 阅读1分钟

在Cluster入口处,当走到step4时,就会涉及到Directory了。

先看下Directory的类图

step4时首先进入

//AbstractDirectory
public List<Invoker<T>> list(Invocation invocation) throws RpcException {
        //抽象方法,子类实现
        List<Invoker<T>> invokers = doList(invocation);//5  RegistryDirectory.doList-->6 7
        //  根据路由规则,找出 Invoker 集合
        List<Router> localRouters = this.routers; //  local reference  本地引用,避免并发问题
        if (localRouters != null && !localRouters.isEmpty()) {
            for (Router router : localRouters) {
                if (router.getUrl() == null || router.getUrl().getParameter(Constants.RUNTIME_KEY, false)) {
                        invokers = router.route(invokers, getConsumerUrl(), invocation);//6 
                    }
            }
        }
        return invokers;
    }

//RegistryDirectory
public List<Invoker<T>> doList(Invocation invocation) {
        List<Invoker<T>> invokers = null;
        Map<String, List<Invoker<T>>> localMethodInvokerMap = this.methodInvokerMap; // local reference
        if (localMethodInvokerMap != null && localMethodInvokerMap.size() > 0) {
            String methodName = RpcUtils.getMethodName(invocation);
            Object[] args = RpcUtils.getArguments(invocation);
            if (args != null && args.length > 0 && args[0] != null
                    && (args[0] instanceof String || args[0].getClass().isEnum())) {
                //way1.根据第一个参数枚举路由。用不到。忽略
                invokers = localMethodInvokerMap.get(methodName + args[0]); 
            }
            if (invokers == null) {
                //way2.根据方法名获得 Invoker 集合(基本到这里就会找到)
                invokers = localMethodInvokerMap.get(methodName);
            }
            //way3.使用全量 Invoker 集合
            if (invokers == null) {
                invokers = localMethodInvokerMap.get("*");
            }
            if (invokers == null) {
                //way4.使用 methodInvokerMap 第一个 Invoker 集合。防御性编程。
                Iterator<List<Invoker<T>>> iterator = localMethodInvokerMap.values().iterator();
                if (iterator.hasNext()) {
                    invokers = iterator.next();
                }
            }
        }
        return invokers == null ? new ArrayList<Invoker<T>>(0) : invokers;
    }