You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@dubbo.apache.org by "iamhaley (GitHub)" <gi...@apache.org> on 2019/08/20 12:53:56 UTC

[GitHub] [dubbo] iamhaley commented on issue #2808: dubbo zookeeper上出现大量的节点,并且出现很多数字252525,导致Len error 16809104

同遇到该问题,原因是人为或程序往注册中心上写了带特殊字符的path(例如 ':' 、'<' 、'?' 等)。

问题原因:
无论是dubbo消费方,还是使用dubbo-admin,dubbo-keeper,都会使用到Registry实现类去订阅服务信息。
以我司使用zookeeper注册中心为例,ZookeeperRegistry订阅服务接口doSubscribe,非订阅所有服务(订阅到的URL服务名为Constants.ANY_VALUE, 即'*')的情况下,则执行下面分支代码:
```
// ZookeeperRegistry源代码
for (String path : toCategoriesPath(url)) {
    ...
    zkClient.create(path, false);
    ...
}
notify(url, listener, urls);
```
问题出在toCategoriesPath这个方法里,因为可以看到后面是会把toCategoriesPath(url)后的path往zk上写临时节点。
toCategoriesPath中有个toServicePath方法:
```
String name = url.getServiceInterface();
	if (Constants.ANY_VALUE.equals(name)) {
	    return toRootPath();
	}
return toRootDir() + URL.encode(name);
```
问题就出现在URL.encode(name)上,如果带有特殊字符的服务往zk上注册,它的url就会被编码,然后就出现开头的%25。由于dubbo的推送机制,新注册的path信息又会被消费方订阅到,然后走到相同的代码中,再次被编码,此时%号又被编码为%25,以此无限循环,发现服务名不断变长,path节点一直在增加。就出现了楼主所所述的问题。
这个问题导致的另一个问题是,zkClient默认读取节点信息的package大小有限制,所以当服务path增长到一定程度时,zkClient将报错无法再读取到服务信息,此时消费方无法再更新服务上下线信息。
当然,这个死循环也导致zk服务器IO打满,CPU100%,最后挂了。 

解决办法:
一般写dubbo服务,Java类命名与XML规范就规避了这种特殊字符的问题。特殊情况是使用泛华调用的时候用字符串写服务名称,命名上可能就放飞自我了。又例如我司的情况,有同步zk上path节点的场景,使用自研程序做这个事情的时候出现bug导致往path上写了特殊字符,从而触发上述问题。

我们更正同步器的bug,同时在dubbo-admin,dubbo-keeper的订阅服务处增加对URL特殊字符的过滤逻辑。不过如果有人手写去改动path信息,那消费方的dubbo源代码还是会触发这个问题(🌚感觉发现一种报复手段),我能想到的就是重新编译更新dubbo的jar包来解决了。


[ Full content available at: https://github.com/apache/dubbo/issues/2808 ]
This message was relayed via gitbox.apache.org for notifications@dubbo.apache.org