dangdangdotcom / dubbox

Dubbox now means Dubbo eXtensions, and it adds features like RESTful remoting, Kyro/FST serialization, etc to the Dubbo service framework.
http://dangdangdotcom.github.io/dubbox
Apache License 2.0
4.89k stars 2.06k forks source link

禁用一个服务的所有提供者后,消费者依然可以调用该远程服务(消费者不重启) #262

Open huifrank opened 7 years ago

huifrank commented 7 years ago

在 com.alibaba.dubbo.rpc.cluster.support.AbstractClusterInvoker;中的成员属性

protected final Directory<T> directory;中存有当前所有可供调用的invokers,如果全部provider没有全部禁用,则一切正常,如果对应provider全部被禁用,directory中会保存最后一个被禁用的invoker,导致调用成功

huifrank commented 7 years ago

补充: RegistryDirectory#refreshInvoker()-> `

        //如果计算错误,则不进行处理.
        if (newUrlInvokerMap == null || newUrlInvokerMap.size() == 0 ){
            logger.error(new IllegalStateException("urls to invokers error .invokerUrls.size :"+invokerUrls.size() + ", invoker.size :0. urls :"+invokerUrls.toString()));
            return ;
        }
        this.methodInvokerMap = multiGroup ? toMergeMethodInvokerMap(newMethodInvokerMap) : newMethodInvokerMap;
        this.urlInvokerMap = newUrlInvokerMap;
        try{
            destroyUnusedInvokers(oldUrlInvokerMap,newUrlInvokerMap); // 关闭未使用的Invoker
        }catch (Exception e) {
            logger.warn("destroyUnusedInvokers error. ", e);
        }

`

当禁用的为一个服务的最后一个提供者时,newUrlInvokerMap == null成立,直接打log并返回,并没有执行 destroyUnusedInvokers(oldUrlInvokerMap,newUrlInvokerMap); // 关闭未使用的Invoker 所以一下代码将永远不会被执行 RegistryDirectory#destroyUnusedInvokers() -> `

    if (newUrlInvokerMap == null || newUrlInvokerMap.size() == 0) {
        destroyAllInvokers();
        return;
    }

`

So....当禁用带所有提供者时,其实还有最后一个被禁用的提供者依然可以被调用

So,,