zookeeper-java-api
1.创建maven项目
2.引入依赖: zookeeper netty log4j slf4j slf4j-log4j jline junit
<dependencies>
<!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.14</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.42.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/jline/jline -->
<dependency>
<groupId>jline</groupId>
<artifactId>jline</artifactId>
<version>0.9.94</version>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
3.编写class,连接zookeeper并创建一个节点。
package zk;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
public class SimpleZkClient {
private static final String connectString="192.168.159.128:2181,192.168.159.130:2181,192.168.159.131:2181";
private static final int sessionTimeout = 10000;
public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
final CountDownLatch countDownLatch = new CountDownLatch(1);
ZooKeeper zkClient = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
public void process(WatchedEvent watchedEvent) {
//收到事件通知之后的回调函数(我们自己的事件处理逻辑),可以什么都不写(不做处理)
if (Watcher.Event.KeeperState.SyncConnected.equals(watchedEvent.getState())){
System.out.println("连接成功" + watchedEvent);
countDownLatch.countDown();
}
System.out.println(watchedEvent.getType() + "---" + watchedEvent.getPath());//输出事件类型和发生事件的节点
}
});
if (ZooKeeper.States.CONNECTING.equals(zkClient.getState())){
System.out.println("连接中");
countDownLatch.await();
}
//数据节点的增删改查
Stat stat = new Stat();
//参数1 要创建的节点的路径 参数2 数据 byte[]类型 参数3 节点权限 参数4 节点类型
String nodeCreated = zkClient.create("/eclipse", "hello zk".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
}
连接成功!打印的null是初始化中syso的内容,表示当前没有监听到事件。
现在我们将代码结构调整下,变成可测试的,并新增get节点及监听功能:
package zk;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.CountDownLatch;
public class SimpleZkClient {
private static final String connectString="192.168.159.128:2181,192.168.159.130:2181,192.168.159.131:2181";
private static final int sessionTimeout = 10000;
ZooKeeper zkClient = null;
@Before
public void init() throws IOException, InterruptedException {
final CountDownLatch countDownLatch = new CountDownLatch(1);
zkClient = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
public void process(WatchedEvent watchedEvent) {
//收到事件通知之后的回调函数(我们自己的事件处理逻辑),可以什么都不写(不做处理)
if (Watcher.Event.KeeperState.SyncConnected.equals(watchedEvent.getState())){
System.out.println("连接成功" + watchedEvent);
countDownLatch.countDown();
}
System.out.println(watchedEvent.getType() + "---" + watchedEvent.getPath());//输出事件类型和发生事件的节点
}
});
if (ZooKeeper.States.CONNECTING.equals(zkClient.getState())){
System.out.println("连接中");
countDownLatch.await();
}
}
//数据节点的增删改查
//创建数据节点到zk中
public void testCreate() throws KeeperException, InterruptedException {
//参数1 要创建的节点的路径 参数2 数据 byte[]类型 参数3 节点权限 参数4 节点类型
String nodeCreated = zkClient.create("/eclipse", "hello zk".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
@Test
public void getChildren() throws KeeperException, InterruptedException {
List<String> children = zkClient.getChildren("/", true);
for(String child:children){
System.out.println(child);
}
Thread.sleep(Long.MAX_VALUE);
}
}
我们首先运行一下测试,结果打印出了节点。
现在我们在服务器中,增加一个节点,观察idea控制台是否监听到内容。
在idea控制台中:
我们发现监听到了创建节点的事件,发生的路径是根路径。这里我们如果是修改一个节点则不会被监听到,因为事件监听有不同的类型,我们在getChirlden中引用的watch是创建节点时的watch,因此它只能监听创建节点事件。
如果我们这时再创建一个节点也不会被监听,因为监听器只生效一次!这显然不符合我们一般的业务场景,因此我们需要对代码做出一些改进,使它能够一直监听。修改init部分。
@Before
public void init() throws Exception {
final CountDownLatch countDownLatch = new CountDownLatch(1);
zkClient = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
public void process(WatchedEvent watchedEvent) {
//收到事件通知之后的回调函数(我们自己的事件处理逻辑),可以什么都不写(不做处理)
if (Watcher.Event.KeeperState.SyncConnected.equals(watchedEvent.getState())){
//System.out.println("连接成功" + watchedEvent);
countDownLatch.countDown();
}
System.out.println(watchedEvent.getType() + "---" + watchedEvent.getPath());//输出事件类型和发生事件的节点
try {
zkClient.getChildren("/", true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
if (ZooKeeper.States.CONNECTING.equals(zkClient.getState())){
System.out.println("连接中");
countDownLatch.await();
}
}
这样我们就可以一直监听到节点变化了.