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();
}
}
這樣我們就可以一直監聽到節點變化了.