集成 Dubbo Spring Boot 时的 ZooKeeper 版本问题

栏目: 服务器 · 发布时间: 6年前

内容简介:微服务节点使用主要情况是配置好了检查堆栈发现是 Dubbo 建立 ZooKeeper 链接的时候,就直接抛出了异常:

微服务节点使用 Spring Boot 会方便很多,在搭建 Spring Boot 的时候碰到了个不大不小的问题,在这里记录下。

主要情况是配置好了 Dubbo Spring Boot 启动 Provider 节点的时候发现异常,抛出了两个错误:

Caused by: org.apache.zookeeper.KeeperException$UnimplementedException: KeeperErrorCode = Unimplemented for ...
Caused by: java.lang.IllegalStateException: KeeperErrorCode = Unimplemented for ...

检查堆栈发现是 Dubbo 建立 ZooKeeper 链接的时候,就直接抛出了异常:

// from com.alibaba.dubbo.registry.zookeeper.ZookeeperRegistry.doRegister(ZookeeperRegistry.java:116) ~[dubbo-2.6.2.jar:2.6.2]

protected void doRegister(URL url) {
    try {
        this.zkClient.create(this.toUrlPath(url), url.getParameter("dynamic", true));
    } catch (Throwable var3) {
        throw new RpcException("Failed to register " + url + " to zookeeper " + this.getUrl() + ", cause: " + var3.getMessage(), var3);
    }
}

但是 ZooKeeper 的服务器配置是正常的,百思不得:

$ echo stat | nc localhost 2181
Zookeeper version: 3.4.13, built on 06/29/2018 04:05 GMT

然后继续查看 KeeperException$UnimplementedException 异常的定义,

``
public static class UnimplementedException extends KeeperException {
    public UnimplementedException() {
        super(Code.UNIMPLEMENTED);
    }
}
```

对应的调用:

// @from org.apache.zookeeper.ZooKeeper.create
public String create(final String path, byte data[], List<ACL> acl,
        CreateMode createMode, Stat stat, long ttl)
        throws KeeperException, InterruptedException {
    final String clientPath = path;
    PathUtils.validatePath(clientPath, createMode.isSequential());
    EphemeralType.validateTTL(createMode, ttl);

    final String serverPath = prependChroot(clientPath);

    RequestHeader h = new RequestHeader();
    setCreateHeader(createMode, h);
    Create2Response response = new Create2Response();
    if (acl != null && acl.size() == 0) {
        throw new KeeperException.InvalidACLException();
    }
    Record record = makeCreateRecord(createMode, serverPath, data, acl, ttl);
    ReplyHeader r = cnxn.submitRequest(h, record, response, null);
    if (r.getErr() != 0) { // 这里抛出的异常
        throw KeeperException.create(KeeperException.Code.get(r.getErr()),
                clientPath);
    }
    if (stat != null) {
        DataTree.copyStat(response.getStat(), stat);
    }
    if (cnxn.chrootPath == null) {
        return response.getPath();
    } else {
        return response.getPath().substring(cnxn.chrootPath.length());
    }
}

那么基本上可以判定 1、是 ZooKeeper 本身链接的问题,和 Dubbo 没有关系;2、实际上 ZooKeeper 本身的服务已经连接上,但 makeCreateRecord 方法调用出现了异常。

那么,可以得出结论是 Java 端和 ZooKeeper 服务端出现了通讯问题。然后发现日志上 jar 包的版本是 zookeeper-3.5.3-beta.jar ,同时查看了下 Manifest 内容如下:

Implementation-Title: org.apache.zookeeper
Implementation-Version: 3.5.3-beta
Implementation-Vendor: The Apache Software Foundation

然后再运行客户端查看了下服务器的版本,两者版本不一致,突然觉得应该是版本的问题。

$ echo stat | nc localhost 2181
Zookeeper version: 3.4.13, built on 06/29/2018 04:05 GMT

很明显 Java 端的版本比服务端的版本要新,那么考虑使用和服务端同个版本的 jar 包试试。

修改对应 build.gradle 的 dependencies 如下,不要纳入 dubbo-spring-boot-starter 提供的 ZooKeeper 的 jar 包

dependencies {
    // ...
    compile('com.alibaba.boot:dubbo-spring-boot-starter:0.2.0') {
        exclude(module: 'org.apache.zookeeper')
    }
    compile 'org.apache.zookeeper:zookeeper:3.4.13'
}

然后再运行 gradle clean bootRun -x test 发现 Dubbo 正常启动,问题解决。

这个问题有点坑,同时很难发现,我又查了下对应的资料。 官方其实已经有对应说明 ,简单的说就是 ZooKeeper 3.5.x 和 ZooKeeper 3.4.x 有不兼容的情况。

而回过头来看 dubbo-spring-boot-starter 包的 pom.xml 定义,对应的 ZooKeeper 这块的引用是这样子的:

<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
</dependency>

没有指定版本,也就是默认是取 Maven 库的最新版本 ,目前是 3.5.4-beta 自然对应本地版本 3.4.13 就有冲突了(竟然不向下兼容,坑)。

相关讨论,看来被坑的不止我: https://stackoverflow.com/questions/35734590/apache-curator-unimplemented-errors-when-trying-to-create-znodes

最后顺便说一句,如果有用到 Spring Cloud 相关的 Zookeeper 组件,也要留个心眼:

dependencies {
    // ...
    compile('org.springframework.cloud:spring-cloud-starter-zookeeper-config') {
        exclude group: 'org.apache.zookeeper', module: 'zookeeper'
    }
    compile('org.springframework.cloud:spring-cloud-starter-zookeeper-discovery') {
        exclude group: 'org.apache.zookeeper', module: 'zookeeper'
    }
    compile 'org.apache.zookeeper:zookeeper:3.4.13'
}

这样子就能保证统一引用的是指定版本的 ZooKeeper 的 jar 包了。

总结下, dubbo-spring-boot-starter 项目目前相对来说还是比较新,相关的文档还是没跟上,但是已经能够日常和生产环境使用了,还是推荐使用简化配置提高些开发效率。

- eof -


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Hacking Growth

Hacking Growth

Sean Ellis、Morgan Brown / Crown Business / 2017-4-25 / USD 29.00

The definitive playbook by the pioneers of Growth Hacking, one of the hottest business methodologies in Silicon Valley and beyond. It seems hard to believe today, but there was a time when Airbnb w......一起来看看 《Hacking Growth》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具