Zookeeper的java客戶端API
zookeeper-api基本使用
org.apache.zookeeper.Zookeeper是客戶端入口主類,負責建立與server的會話。它提供了以下 所示幾類主要方法。
demo增刪改查
我們先修改一下本地的hosts檔案
並且測試一下:
現在我們來看看zookeeper的java客戶端api:
我們先來初始化一下zookeeper。
public class SimpleZkClient {
private static final String connectString = "mini1:2181,mini2:2181,mini3:2181";
private static final int sessionTimeout = 2000;
ZooKeeper zkClient = null;
@Before
public void init() throws Exception {
zkClient = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent event) {
// 收到事件通知後的回撥函式(應該是我們自己的事件處理邏輯)
System.out.println(event.getType() + "---" + event.getPath());
}
});
}
}
我們new一個zookeeper物件,裡面的引數connectString是叢集的zookeeper的ip和埠,sessionTimeout 是連線超時的時間,Watcher是我們的監聽器。
建立節點
然後我們來看看zookeeper的建立節點的操作:
// 建立資料節點到zk中
@Test
public void testCreate() throws KeeperException, InterruptedException {
// 引數1:要建立的節點的路徑 引數2:節點大資料 引數3:節點的許可權 引數4:節點的型別
String nodeCreated = zkClient.create("/eclipse", "hellozk".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
//上傳的資料可以是任何型別,但都要轉成byte[]
}
然後我們可以看到我們根節點下面就有eclipse這個子節點了。
判斷路徑節點是否存在
然後我們還可以判斷路徑節點是否存在:
//判斷znode是否存在
@Test
public void testExist() throws Exception{
Stat stat = zkClient.exists("/eclipse", false);
System.out.println(stat==null?"not exist":"exist");
}
獲取節點下面的所有子節點
獲取節點下面的所有子節點的操作:
// 獲取子節點
@Test
public void getChildren() throws Exception {
List<String> children = zkClient.getChildren("/", true);//true表示使用初始化zookeeper時候設定的那個Watcher
for (String child : children) {
System.out.println(child);
}
Thread.sleep(Long.MAX_VALUE);
}
我們上面使用Thread.sleep(Long.MAX_VALUE)
是為了使程式不退出,便於觀察到監聽器的觸發。
然後我們在zookeeper命令列客戶端中建立一個新的節點,檢視一下是否會觸發事件。
然後我們可以看到觸發了監聽器:
我們再建立一個子節點,可以發現並不會再次觸發監聽器,監聽器只觸發一次。
我們可以在監聽器觸發完畢之後再註冊一個監聽器。
@Before
public void init() throws Exception {
zkClient = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent event) {
// 收到事件通知後的回撥函式(應該是我們自己的事件處理邏輯)
System.out.println(event.getType() + "---" + event.getPath());
try {
//重新註冊監聽
zkClient.getChildren("/", true);
} catch (Exception e) {
}
}
});
}
然後我們現在再來試一次。
我們可以發現,可以多次觸發監聽事件。
通過上面這中方式我們保證了能夠不停的觸發監聽事件。
Zookeeper的監聽器工作機制
現在我們來了解一下Zookeeper的監聽器工作機制,zookeeper是如何觸發監聽事件的?
現在我們的zookeeper客戶端程式裡面有一個main執行緒,然後在裡面建立了一個zkclient,在這個時候就啟動了兩個執行緒。一個執行緒是Connector的客戶端,用於和zookeeper連線去上傳資料、請求資料等;還有一個執行緒是Listener,可以去呼叫我們程式碼裡面的process方法,它會監聽在一個埠。當我們呼叫zkClient.getChildren("/", true);
其實就是通過Connector通訊執行緒告訴zookeeper我們監聽器的通訊IP和埠以及監聽的path;zookeeper就會記錄這些IP、埠、path,當path下的資料發生了變化,zookeeper就知道觸發事件的客戶端在哪裡(通過IP和埠可以找到),然後可以通過socket通訊也就是通過RPC去遠端呼叫客戶端,客戶端收到事件只會就會去回撥process方法。
獲取znode的資料
@Test
public void getData() throws Exception {
byte[] data = zkClient.getData("/eclipse", false, null);
System.out.println(new String(data));
}
刪除znode
@Test
public void deleteZnode() throws Exception {
//引數2:指定要刪除的版本,-1表示刪除所有版本
zkClient.delete("/eclipse", -1);
}
設定znode的資料
@Test
public void setData() throws Exception {
zkClient.setData("/eclipse", "aaaaaa".getBytes(), -1);
byte[] data = zkClient.getData("/eclipse", false, null);
System.out.println(new String(data));
}