1 概述
使用 zookeeper 作为注册中心,构建 dubbo 服务提供者和消费者。
2 项目环境
(1)依赖的jar包
java
jdk 21
dubbo 3.2.7
zookeeper 3.8.5
spring boot 3.1.5
(2)服务注册中心
zookeeper 服务器版本 3.8.5
3 安装 zookeeper
(1)下载安装包
访问 Zookeeper 官方下载页面:Zookeeper 下载,下载 apache-zookeeper-3.8.5-bin.tar.gz.
(2)安装和配置
安装:解压上述压缩包即可。
修改配置:进入 conf 目录,复制并重命名文件 zoo_sample.cfg 为 zoo.cfg。修改 zoo.cfg 中的配置(可选),修改内容如下:
java
dataDir=/tmp/zookeeper/data
dataLogDir=/tmp/zookeeper/log
admin.serverPort=8888
修改环境变量(可选):将 zookeeper/bin 目录添加到 Path 环境变量中,以便从cmd窗口直接执行 Zookeeper 命令。
(3)启动
在cmd窗口使用命令"zkServer.cmd"启动 zookeeper。
(4)判断是否启动成功
在cmd窗口使用命令"zkCli.cmd"启动客户端。使用命令"ls /",返回"[zookeeper]"即代表启动成功。
或者在cmd窗口使用 netstat 命令检查 zookeeper 端口是否被监听。有被监听到即代表启动成功。
netstat -an | findstr :2181
4 注意事项
(1)依赖的 zookeeper jar包版本尽量与 zookeeper 服务器版本一致。
5 问题
(1)依赖包版本问题。zookeeper jar包版本为 3.4.14 时,dubbo服务连接zookeeper失败
java
2026-01-05T14:37:14.332+08:00 WARN 35896 --- [127.0.0.1:2181)] org.apache.zookeeper.ClientCnxn : Session 0x0 for server 127.0.0.1/<unresolved>:2181, unexpected error, closing socket connection and attempting reconnect
java.lang.IllegalArgumentException: Unable to canonicalize address 127.0.0.1/<unresolved>:2181 because it's not resolvable
at org.apache.zookeeper.SaslServerPrincipal.getServerPrincipal(SaslServerPrincipal.java:65) ~[zookeeper-3.4.14.jar:3.4.14-4c25d480e66aadd371de8bd2fd8da255ac140bcf]
at org.apache.zookeeper.SaslServerPrincipal.getServerPrincipal(SaslServerPrincipal.java:41) ~[zookeeper-3.4.14.jar:3.4.14-4c25d480e66aadd371de8bd2fd8da255ac140bcf]
at org.apache.zookeeper.ClientCnxn$SendThread.startConnect(ClientCnxn.java:1001) ~[zookeeper-3.4.14.jar:3.4.14-4c25d480e66aadd371de8bd2fd8da255ac140bcf]
at org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1060) ~[zookeeper-3.4.14.jar:3.4.14-4c25d480e66aadd371de8bd2fd8da255ac140bcf]
原因 :zookeeper jar包版本为 3.4.14 时,解析zookeeper地址出错。
在调用 java.net.InetSocketAddress.InetSocketAddressHolder#toString 时,解析出来的地址为"127.0.0.1/<unresolved>:2181"。调用的源码如下:
java
public String toString() {
String formatted;
if (isUnresolved()) {
formatted = hostname + "/<unresolved>";
} else {
formatted = addr.toString();
if (addr instanceof Inet6Address) {
int i = formatted.lastIndexOf("/");
formatted = formatted.substring(0, i + 1)
+ "[" + formatted.substring(i + 1) + "]";
}
}
return formatted + ":" + port;
}
解决:使用版本为 3.8.5 的 zookeeper 的jar包。