欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2023-12-27 16:40:15
...

最近在做项目的时候,因为要调试,所以选择了直连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配置文件,以及错误日志,终于发现问题:同一个服务引用我定义了两次!!!!!只有其中一个配置了直连,另一个没有配置直连,就去注册中心查找服务,注册中心没有服务自然就报错了。

 
解决:

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

 

其他:

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

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

 

 

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

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

网上有一个文档叫做:《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

 

 

 

 

 

上一篇:

下一篇: