1. 程式人生 > >Zookeeper的java客戶端API

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));

    }

這裡寫圖片描述