运行中ZooKeeper实例真实版本查询及显示不符问题求助
ZooKeeper版本显示异常:实际3.4.11却显示3.4.5的排查方案
看起来你遇到了典型的类加载优先级问题——明明部署的是ZooKeeper 3.4.11,但运行实例却加载了旧版本3.4.5的类。咱们一步步来定位解决:
一、先定位问题根源:哪个Jar在提供旧版本类
从你给出的进程信息来看,zookeeper-3.4.11.jar确实在classpath中,但classpath里的其他Jar可能包含了旧版本的ZooKeeper类,且被JVM优先加载了。
1. 扫描所有classpath中的Jar,找出带ZooKeeper类的文件
执行以下命令(对应你进程中的classpath路径),检查每个Jar里的ZooKeeper版本:
for jar in /opt/zookeeper-server/default/bin/../build/lib/*.jar /opt/zookeeper-server/default/bin/../lib/*.jar /opt/zookeeper-server/default/bin/../src/java/lib/*.jar; do # 检查Jar中是否包含ZooKeeper的Version类 if unzip -l "$jar" | grep -q "org/apache/zookeeper/Version.class"; then echo -e "\n=== 检查Jar: $jar ===" # 提取版本信息 unzip -p "$jar" org/apache/zookeeper/Version.class | javap -c | grep -E "ZOO_KEEPER_VERSION|version" fi done
这个命令会输出每个包含ZooKeeper类的Jar对应的版本号,你能直接找到提供3.4.5版本的Jar。
2. 直接从运行中的JVM获取类加载来源
如果扫描没发现问题,还可以直接查询当前ZK进程(PID为19002)中Version类的加载位置:
# 切换到进程所属用户执行 sudo -u myuser jcmd 19002 ClassLoader.loadClass org.apache.zookeeper.Version
这个命令会明确显示Version类是从哪个Jar文件加载的,一眼就能定位到问题Jar。
二、常见问题原因及解决方法
根据经验,大概率是以下两种情况:
- Exhibitor内置了旧版本ZK类:你使用的Exhibitor 1.6.0可能依赖并内置了ZooKeeper 3.4.5的类,导致优先加载。解决方法:
- 用上面的扫描命令检查
exhibitor-1.6.0.jar是否包含ZK类,如果是,替换成与ZK 3.4.11兼容的Exhibitor版本,或者修改Exhibitor的classpath顺序,让zookeeper-3.4.11.jar排在exhibitor-1.6.0.jar前面。
- 用上面的扫描命令检查
- classpath中存在旧版本ZK Jar:比如
build/lib或src/java/lib目录下遗留了zookeeper-3.4.5.jar,直接删除这个旧Jar即可。
三、验证修复结果
调整完classpath或删除旧Jar后,重启ZooKeeper服务,再用telnet localhost 2181执行stats命令,就能看到正确的3.4.11版本了。你也可以用ZK自带的客户端工具验证:
/opt/zookeeper-server/default/bin/zkCli.sh -server localhost:2181 version
内容的提问来源于stack exchange,提问作者SnwBr
相关产品推荐
相关产品推荐

