ZooKeeper是用Java开发的,3.4.6版本的Java API文档可以在上找到。
Tips
本章的代码在Linux操作系统下进行测试,运行ZooKeeper服务器实例的版本为3.4.6。
开发应用程序的ZooKeeper Java绑定主要由两个Java包组成:
org.apache.zookeeper
org.apache.zookeeper.data
org.apache.zookeeper包由ZooKeeper监视的接口定义和ZooKeeper的各种回调处理程序组成。 它定义了ZooKeeper客户端类库的主要类以及许多ZooKeeper事件类型和状态的静态定义。 org.apache.zookeeper.data包定义了与数据寄存器(也称为znode)相关的特性,例如访问控制列表(ACL),IDs,stats等。
ZooKeeper Java API中的org.apache.zookeeper.server,org.apache.zookeeper.server.quorum和org.apache.zookeeper.server.upgrade包是服务器实现的一部分。 org.apache.zookeeper.client包用于查询ZooKeeper服务器的状态。
一 准备开发环境Apache ZooKeeper是一个复杂的软件,因此它需要运行许多其他类库。 依赖库作为jar文件在ZooKeeper发行版中附带在lib目录中。 核心ZooKeeper jar文件名字为zookeeper-3.4.6.jar,位于主目录下。
要开发Java的ZooKeeper应用程序,我们必须设置指向ZooKeeper jar的类路径,以及ZooKeeper所依赖的所有第三方库。在 bin 目录下有一个 zkEnv.sh文件,可以用来设置CLASSPATH。
我们需要将脚本如下设置,在命令行中执行以下语句:
$ ZOOBINDIR=${ZK_HOME}/bin $ source ${ZOOBINDIR}/zkEnv.shshell变量ZK_HOME被设置为安装ZooKeeper的路径,在我的设置中,它是/usr/share/zookeeper。 之后,CLASSPATH变量被正确设置,在我的系统中,如下所示:
$ echo $CLASSPATH /usr/share/zookeeper-3.4.6/bin/../build/classes :/usr/share/zookeeper-3.4.6/bin/../build/lib/*.jar :/usr/share/zookeeper-3.4.6/bin/../lib/slf4j-log4j12-1.6.1.jar :/usr/share/zookeeper-3.4.6/bin/../lib/slf4j-api-1.6.1.jar :/usr/share/zookeeper-3.4.6/bin/../lib/netty-3.7.0.Final.jar :/usr/share/zookeeper-3.4.6/bin/../lib/log4j-1.2.16.jar :/usr/share/zookeeper-3.4.6/bin/../lib/jline-0.9.94.jar :/usr/share/zookeeper-3.4.6/bin/../zookeeper-3.4.6.jar :/usr/share/zookeeper-3.4.6/bin/../src/java/lib/*.jar :/usr/share/zookeeper-3.4.6/bin/../conf:在Windows操作系统中,需要运行zkEnv.cmd脚本。 现在可以使用CLASSPATH变量来编译和运行使用ZooKeeper API编写的Java程序。 可以在Uni/Linux中的主目录的.bashrc文件中找到zkEnv.sh脚本,避免每次启动shell会话时都采用它。
二 第一个ZooKeeper程序为了引入ZooKeeper Java API,让我们从一个非常简单的程序开始,它可以连接到localhost中的ZooKeeper实例,如果连接成功,它将在ZooKeeper名称空间的根路径下打印znode的列表。
这个程序的代码如下所示:
/*Our First ZooKeeper Program*/ import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.ZooKeeper; public class HelloZooKeeper { public static void main(String[] args) throws IOException { String hostPort = "localhost:2181"; String zpath = "http://www.likecs.com/"; List <String> zooChildren = new ArrayList<String>(); ZooKeeper zk = new ZooKeeper(hostPort, 2000, null); if (zk != null) { try { zooChildren = zk.getChildren(zpath, false); System.out.println("Znodes of 'http://www.likecs.com/': "); for (String child: zooChildren) { //print the children System.out.println(child); } } catch (KeeperException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } } }在构建和执行前面的代码片段之前,让我们来看看它具体做了什么。代码从导入语句开始。使用这些语句,我们导入了程序各个组件所需的包。如前所述,org.apache.zookeeper包包含客户端与ZooKeeper服务器进行交互所需的所有类和接口。在导入包之后,定义了一个名为HelloZooKeeper的类。由于我们要连接到在同一系统中运行的ZooKeeper实例,在main方法中将主机和端口字符串定义为localhost:2181。代码行zk = new ZooKeeper(hostPort, 2000, null)调用ZooKeeper构造方法,该构造方法尝试连接到ZooKeeper服务器并返回一个引用。对于连接到ZooKeeper服务器实例并维护该连接的客户端程序,需要维护一个实时会话。在此例中,构造方法实例化的zk对象返回的引用表示这个会话。 ZooKeeper API是围绕这个引用构建的,每个方法调用都需要一个引用来执行。
ZooKeeper类的构造方法使用以下代码创建ZooKeeper实例的引用:
ZooKeeper(String connectString, int sessionTimeout, Watcher watcher)使用的参数含义如下:
connectString:以逗号分隔的主机:端口号列表,每个对应一个ZooKeeper服务器。 例如,10.0.0.1:2001,10.0.0.2:2002和10.0.0.3:2003表示三个节点的ZooKeeper ensemble的有效的主机:端口匹配对。
sessionTimeout:这是以毫秒为单位的会话超时时间。这是ZooKeeper在宣布session结束 之前,没有从客户端获得心跳的时间。