dubbo 直连报Forbid consumer...Please check registry access list (whitelist/blacklis

最近在做项目的时候,因为要调试,所以选择了直连dubbo

按照官方文档给出的配置

配置为:

<dubbo:reference id="xxxService" interface="com.alibaba.xxx.XxxService" url="dubbo://localhost:20890" />

但是使用的时候还是报错,堆栈信息如下:

com.alibaba.dubbo.rpc.RpcException: Forbid consumer xx.xx.xx.xx access service xx.xx.xxx.xxx.xxx.xxx from registry 127.0.0.1:2181 use dubbo version 2.5.3, Please check registry access list (whitelist/blacklist).
	at com.alibaba.dubbo.registry.integration.RegistryDirectory.doList(RegistryDirectory.java:579) ~[dubbo-2.5.3.jar:2.5.3]
	at com.alibaba.dubbo.rpc.cluster.directory.AbstractDirectory.list(AbstractDirectory.java:73) ~[dubbo-2.5.3.jar:2.5.3]
	at com.alibaba.dubbo.rpc.cluster.support.AbstractClusterInvoker.list(AbstractClusterInvoker.java:260) ~[dubbo-2.5.3.jar:2.5.3]
	at com.alibaba.dubbo.rpc.cluster.support.AbstractClusterInvoker.invoke(AbstractClusterInvoker.java:219) ~[dubbo-2.5.3.jar:2.5.3]
	at com.alibaba.dubbo.rpc.cluster.support.wrapper.MockClusterInvoker.invoke(MockClusterInvoker.java:72) ~[dubbo-2.5.3.jar:2.5.3]
	at com.alibaba.dubbo.rpc.proxy.InvokerInvocationHandler.invoke(InvokerInvocationHandler.java:52) ~[dubbo-2.5.3.jar:2.5.3]
	at com.alibaba.dubbo.common.bytecode.proxy2.refundOrderAllMoney(proxy2.java) ~[na:2.5.3]
	at .....

 百思不得其解:不是都直连了么,怎么还有一个注册中心啊?

 
排查:

官方给出的配置应该没错啊。构建一个demo程序,按照上面的配置直连服务提供者,连接成功,没报错。那么问题就出在我的代码里面了

仔细检查dubbo配置文件,以及错误日志,终于发现问题:同一个服务引用我定义了两次!!!!!只有其中一个配置了直连,另一个没有配置直连,就去注册中心查找服务,注册中心没有服务自然就报错了。

扫描二维码关注公众号,回复: 361130 查看本文章
 
解决:

删除掉重复的服务引用,问题解决

其他:

因为代码重复引起的问题我已经遇到过三次了,每次都很蛋疼,看代码看到死都看不出来问题。因为问题代码根本就不在那里。所以呢,下次如果遇到这种代码明显没问题,但是执行结果有问题的情况,可以考虑去查下是不是存在代码重复的问题。也许代码执行的是另一个地方呢。

代码重复包括:代码方法定义重复、配置重复、类加载重复、代码版本错误等等等等

---------------------------------------------------------------------------------------------------

(下面的这坨不用看了,本来想写扩展点的,写着写着就不知道在写啥了)

网上有一个文档叫做:《dubbo源码解析2.0.pdf》写得很详细,想了解dubbo实现的可以看看这个文档

扩展:

直连式怎么做到的呢?怎么跳过注册中心的呢?

1) 配置直连服务提供者的时候

在ReferenceConfig.createProxy方法中回去判断引用有没有指定url

if (url != null && url.length() > 0) { // 用户指定URL,指定的URL可能是对点对直连地址,也可能是注册中心URL
                String[] us = Constants.SEMICOLON_SPLIT_PATTERN.split(url);
                if (us != null && us.length > 0) {
                    for (String u : us) {
                        URL url = URL.valueOf(u);
                        if (url.getPath() == null || url.getPath().length() == 0) {
                            url = url.setPath(interfaceName);
                        }
                        if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) {
                            urls.add(url.addParameterAndEncoded(Constants.REFER_KEY, StringUtils.toQueryString(map)));
                        } else {
                            urls.add(ClusterUtils.mergeUrl(url, map));
                        }
                    }
                }
            }

 假设,我们只指定了一个url,并且这个url不是注册中心的url,那么执行这段代码后urls里面就只有一个url,为指定的服务提供者的地址,紧接着上面的代码在下面有这么一句代码

if (urls.size() == 1) {
        invoker = refprotocol.refer(interfaceClass, urls.get(0));
    }

此时的refprotocol.refer在代理类里面执行的时候,会根据url去匹配到对应的Protocol。

直连服务提供者的时候,这里我们配置的url是dubbo://xx.xxx.xxx.xxx:xxxx;那么他的协议时dubbo,就会找到对应的DubboProtocol类,去执行refer方法,在DubboProtocol方法中他就直接根据url创建了客户端,生产了Invoke了

2)没有配置直连服务提供者

没有配置直连服务提供者的时候,在ReferenceConfig.createProxy方法中是执行的这一段路径

else { // 通过注册中心配置拼装URL
   List<URL> us = loadRegistries(false);
   if (us != null && us.size() > 0) {
       for (URL u : us) {
           URL monitorUrl = loadMonitor(u);
            if (monitorUrl != null) {
                map.put(Constants.MONITOR_KEY, URL.encode(monitorUrl.toFullString()));
            }
           urls.add(u.addParameterAndEncoded(Constants.REFER_KEY, StringUtils.toQueryString(map)));
        }
   }
   if (urls == null || urls.size() == 0) {
        throw new IllegalStateException("No such any registry to reference " + interfaceName  + " on the consumer " + NetUtils.getLocalHost() + " use dubbo version " + Version.getVersion() + ", please config <dubbo:registry address=\"...\" /> to your spring config.");
    }
}

  从注册中心去获取可用的服务提供者的url,获取到了之后再依次对这些服务提供者的url进行refer,创建连接,invoker

猜你喜欢

转载自k19421.iteye.com/blog/2309623