Zookeeper 客戶端 API

LZC發表於2020-07-10
<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.4.6</version>
</dependency>

介面說明

ZooKeeper建構函式說明

public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher);

public ZooKeeper(String connectString, 
                 int sessionTimeout,
                 Watcher watcher,
                boolean canBeReadOnly);

public ZooKeeper(String connectString, 
                 int sessionTimeout, 
                 Watcher watcher,
                 long sessionId, 
                 byte[] sessionPasswd);


ZooKeeper(String connectString, 
          int sessionTimeout, 
          Watcher watcher,
          long sessionId, 
          byte[] sessionPasswd, 
          boolean canBeReadOnly);

引數解釋

connectString :zk伺服器列表,由英文逗號分開的字串,

例如:127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183;

sessionTimeout :會話超時時間,以毫秒為單位。在一個會話週期內,zk客戶端和服務端透過心跳來檢查連線的有效性,一旦在sessionTimeout時間內沒有進行心跳檢測,則會話失效。

watcher: zk允許客戶端在構造方法中傳入一個Watcher介面實現類作為事件通知處理器。

canBeReadOnly :在zk叢集模式中,如果一臺叢集和叢集中過半以上的機器都都失去了網路連線,那麼這個機器將不再處理客戶端請求,包括讀寫請求。但在某些情況下出現類似問題,我們希望該臺機器能夠處理讀請求,此時為 read-only 模式。

sessionId、sessionPasswd :利用sessionId 和 sessionPasswd 確保複用會話連線。

程式碼

public class Test {
    // 客戶端 和 服務端 建立會話的過程是非同步的。也就是客戶度透過構造方法建立會話後立即返回,此時的連線並沒有完全建立
    // 真正的會話建立完成後,zk服務端會給客戶端通知一個事件,客戶端獲取通知之後在表明連線正在建立。       
    // 用於等待zk服務端通知
    private static CountDownLatch latch = new CountDownLatch(1);

    private static ZooKeeper zk = null;
    // 如果有多個地址,則使用逗號隔開
    private static final String connString="127.0.0.1:2181";
    // 超時時間
    private static final int sessionTimeout = 2000;

    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
        zk = new ZooKeeper(connString, sessionTimeout, new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                System.out.println("path = " + event.getPath() + ", eventType = " + event.getType() + ", keeperState = " + event.getState());
                if (Event.KeeperState.SyncConnected == event.getState()) {
                    latch.countDown();
                }
            }
        });
        latch.await();
        // 關閉 zk
        zk.close();
    }
}

介面說明

// 同步建立節點
public String create(final String path, byte data[], List<ACL> acl,
            CreateMode createMode);

// 非同步建立節點
public void create(final String path, byte data[], List<ACL> acl,
            CreateMode createMode,  StringCallback cb, Object ctx);

引數解釋

String path:node的路徑

byte data[]:初始化node資料

List acl:node的acl許可權

CreateMode createMode:指定node型別,共有四種型別,如下所示

  1. CreateMode.PERSISTENT:持久化節點,客戶端連線斷開後不會被自動刪除

  2. CreateMode.PERSISTENT_SEQUENTIAL:持久化順序節點

  3. CreateMode.EPHEMERAL:臨時節點,客戶端連線斷開後會被自動刪除

  4. CreateMode.EPHEMERAL_SEQUENTIAL:臨時順序節點

StringCallback cb:非同步回撥函式

Object ctx:用於傳遞上下文資訊

同步建立節點

public class Test {
    // 客戶端 和 服務端 建立會話的過程是非同步的。也就是客戶度透過構造方法建立會話後立即返回,此時的連線並沒有完全建立
    // 真正的會話建立完成後,zk服務端會給客戶端通知一個事件,客戶端獲取通知之後在表明連線正在建立。
    // 用於等待zk服務端通知
    private static CountDownLatch latch = new CountDownLatch(1);

    private static ZooKeeper zk = null;
    // 如果有多個地址,則使用逗號隔開
    private static final String connString="127.0.0.1:2181";
    // 超時時間
    private static final int sessionTimeout = 2000;

    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
        zk = new ZooKeeper(connString, sessionTimeout, new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                System.out.println("path = " + event.getPath() + ", eventType = " + event.getType() + ", keeperState = " + event.getState());
                if (Event.KeeperState.SyncConnected == event.getState()) {
                    latch.countDown();
                }
            }
        });
        latch.await();

        // 臨時節點:建立介面返回該節點路徑L,例如返回值 /zk-test
        String path1 = zk.create("/zk-test", "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
        System.out.println("created path success : " + path1);

        // 臨時順序節點:會自動的在節點路徑後加一個數字,例如返回值:/ zk-test0000000001
        String path2 = zk.create("/zk-test", "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
        System.out.println("created path success : " + path2);

        // 關閉 zk
        zk.close();
    }
}

非同步建立節點

public class Test {
    // 客戶端 和 服務端 建立會話的過程是非同步的。也就是客戶度透過構造方法建立會話後立即返回,此時的連線並沒有完全建立
    // 真正的會話建立完成後,zk服務端會給客戶端通知一個事件,客戶端獲取通知之後在表明連線正在建立。
    // 用於等待zk服務端通知
    private static CountDownLatch latch = new CountDownLatch(1);

    private static ZooKeeper zk = null;
    // 如果有多個地址,則使用逗號隔開
    private static final String connString="127.0.0.1:2181";
    // 超時時間
    private static final int sessionTimeout = 2000;

    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
        zk = new ZooKeeper(connString, sessionTimeout, new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                System.out.println("path = " + event.getPath() + ", eventType = " + event.getType() + ", keeperState = " + event.getState());
                if (Event.KeeperState.SyncConnected == event.getState()) {
                    latch.countDown();
                }
            }
        });
        latch.await();
        System.out.println(zk.getSessionId());
        System.out.println(zk.getSessionPasswd());
        /********************************************************************************************/

        // 持久化節點:建立介面返回該節點路徑,無返回值;非同步建立的節點:/zk-test
        zk.create("/zk-test",
                "".getBytes(),
                ZooDefs.Ids.OPEN_ACL_UNSAFE,
                CreateMode.PERSISTENT,
                new CallBack(),
                "PERSISTENT");

        //持久化順序節點:會自動的在節點路徑後加一個數字,該方法無返回值,建立後節點:/zk-test-seq0000000002
        zk.create("/zk-test-seq",
                "".getBytes(),
                ZooDefs.Ids.OPEN_ACL_UNSAFE,
                CreateMode.PERSISTENT_SEQUENTIAL,
                new CallBack(),
                "PERSISTENT_SEQUENTIAL");

        Thread.sleep(1000);

        // 關閉 zk
        zk.close();
    }

    static class CallBack implements AsyncCallback.StringCallback {
        /**
         * 服務端回撥方法
         *
         * @param code 服務端響應碼:0 介面呼叫成功;-4 客戶端和服務端連線斷開;-110 節點已存在 ;-112 會話過期
         * @param path 建立節點傳入的路徑引數
         * @param ctx  非同步建立api傳入的ctx引數
         * @param name 服務端真正建立節點的名稱,業務邏輯應該以該值為準
         */
        @Override
        public void processResult(int code, String path, Object ctx, String name) {
            System.out.println("created success : code = " + code + ",path = " + path + ",ctx = " + ctx + ",name = " + name);
        }
    }
}

介面說明

// 同步獲取
public byte[] getData(String path, boolean watch, Stat stat);
public byte[] getData(final String path, Watcher watcher, Stat stat);

// 非同步獲取
public void getData(String path, boolean watch, DataCallback cb, Object ctx);
public void getData(final String path, Watcher watcher,
            DataCallback cb, Object ctx);

引數解釋

String path:node的路徑

boolean watch:如果 watch 為 true,該 znode 的狀態變化會傳送給構建 Zookeeper 指定的 watcher

Stat stat:節點的狀態資訊,有時候我們不僅需要最新的子節點列表,還要獲取這個節點的最新狀態資訊,我們可以將一箇舊的 stat 傳入到api方法中,在方法執行過程中 stat 會被來自服務的新的 stat 替換掉。

Watcher watcher:watcher 用來監聽該 znode 的狀態變化

DataCallback cb:非同步回撥函式

Object ctx:用於傳遞上下文資訊

同步獲取資料

public class Test {
    // 客戶端 和 服務端 建立會話的過程是非同步的。也就是客戶度透過構造方法建立會話後立即返回,此時的連線並沒有完全建立
    // 真正的會話建立完成後,zk服務端會給客戶端通知一個事件,客戶端獲取通知之後在表明連線正在建立。
    // 用於等待zk服務端通知
    private static CountDownLatch latch = new CountDownLatch(1);

    private static ZooKeeper zk = null;
    // 如果有多個地址,則使用逗號隔開
    private static final String connString="127.0.0.1:2181";
    // 超時時間
    private static final int sessionTimeout = 2000;

    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
        zk = new ZooKeeper(connString, sessionTimeout, new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                System.out.println("path = " + event.getPath() + ", eventType = " + event.getType() + ", keeperState = " + event.getState());
                if (Event.KeeperState.SyncConnected == event.getState()) {
                    latch.countDown();
                }
            }
        });
        latch.await();

        // 臨時節點:建立介面返回該節點路徑L,例如返回值 /zk-test
        String path1 = zk.create("/zk-data", "test-data".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
        System.out.println("created path success : " + path1);


//        byte[] data = zk.getData("/zk-data", true, null);
//        System.out.println("data = " + new String(data));

        /**
         * 也可以透過如下方式進行監聽
         */
        byte[] data = zk.getData("/zk-data", new Watcher() {
            // 當 /zk-data 節點資訊資料改變時將會觸發這裡
            @Override
            public void process(WatchedEvent event) {
                System.out.println("path = " + event.getPath() + ", eventType = " + event.getType() + ", keeperState = " + event.getState());
            }
        }, null);
        System.out.println("data = " + new String(data));

        // 關閉 zk
        zk.close();
    }
}

介面說明

// 同步設定
// 如果 version 為 -1,則表示無無條件更新。
// 
Stat setData(final String path, byte data[], int version);
// 非同步設定
public void setData(final String path, byte data[], int version,
            StatCallback cb, Object ctx);

引數解釋

String path:node的路徑

byte data[]:更新資料

int version:如果 version 為 -1,則表示無無條件更新;否則只有給定的 version 和 znode 當前的 version 一樣才會進行更新

StatCallback cb:非同步回撥函式

Object ctx:於傳遞上下文資訊

同步修改資料

public class Test {
    // 客戶端 和 服務端 建立會話的過程是非同步的。也就是客戶度透過構造方法建立會話後立即返回,此時的連線並沒有完全建立
    // 真正的會話建立完成後,zk服務端會給客戶端通知一個事件,客戶端獲取通知之後在表明連線正在建立。
    // 用於等待zk服務端通知
    private static CountDownLatch latch = new CountDownLatch(1);

    private static ZooKeeper zk = null;
    // 如果有多個地址,則使用逗號隔開
    private static final String connString="127.0.0.1:2181";
    // 超時時間
    private static final int sessionTimeout = 2000;

    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
        zk = new ZooKeeper(connString, sessionTimeout, new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                System.out.println("path = " + event.getPath() + ", eventType = " + event.getType() + ", keeperState = " + event.getState());
                if (Event.KeeperState.SyncConnected == event.getState()) {
                    latch.countDown();
                }
            }
        });
        latch.await();

        // 臨時節點:建立介面返回該節點路徑L,例如返回值 /zk-test
        String path1 = zk.create("/zk-data", "test-data".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
        System.out.println("created path success : " + path1);

        // 獲取資料
        byte[] data = zk.getData("/zk-data", new Watcher() {
            // 當 /zk-data 節點資訊資料改變時將會觸發這裡
            @Override
            public void process(WatchedEvent event) {
                System.out.println("path = " + event.getPath() + ", eventType = " + event.getType() + ", keeperState = " + event.getState());
            }
        }, null);
        System.out.println("data = " + new String(data));

        // 修改資料
        zk.setData("/zk-data","test-data-update".getBytes(), -1);
        // 獲取資料
        byte[] updateData = zk.getData("/zk-data", true, null);
        System.out.println("updateData = " + new String(updateData));

        // 關閉 zk
        zk.close();
    }
}

介面說明

// 同步刪除
public void delete(final String path, int version);
// 非同步刪除
public void delete(final String path, int version, VoidCallback cb,
            Object ctx)

引數解釋

String path:node的路徑

int version:如果 version 為 -1,則表示無無條件刪除;否則只有給定的 version 和 znode 當前的 version 一樣才會進行刪除

VoidCallbackcb:非同步回撥函式

Object ctx:於傳遞上下文資訊

同步刪除節點

public class Test {
    // 客戶端 和 服務端 建立會話的過程是非同步的。也就是客戶度透過構造方法建立會話後立即返回,此時的連線並沒有完全建立
    // 真正的會話建立完成後,zk服務端會給客戶端通知一個事件,客戶端獲取通知之後在表明連線正在建立。
    // 用於等待zk服務端通知
    private static CountDownLatch latch = new CountDownLatch(1);

    private static ZooKeeper zk = null;
    // 如果有多個地址,則使用逗號隔開
    private static final String connString="127.0.0.1:2181";
    // 超時時間
    private static final int sessionTimeout = 2000;

    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
        zk = new ZooKeeper(connString, sessionTimeout, new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                System.out.println("path = " + event.getPath() + ", eventType = " + event.getType() + ", keeperState = " + event.getState());
                if (Event.KeeperState.SyncConnected == event.getState()) {
                    latch.countDown();
                }
            }
        });
        latch.await();

        // 建立持久化節點
        String path1 = zk.create("/zk-data", "test-data".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

        System.out.println("created path success : " + path1);

        zk.delete("/zk-data",-1);
        // 關閉 zk
        zk.close();
    }
}

介面說明

public Stat exists(String path, boolean watch);
public Stat exists(final String path, Watcher watcher);

public void exists(String path, boolean watch, StatCallback cb, Object ctx);
public void exists(final String path, Watcher watcher,
            StatCallback cb, Object ctx);

引數解釋

這列的引數跟前面的分析是類似的

程式碼實踐

public class Test {
    // 客戶端 和 服務端 建立會話的過程是非同步的。也就是客戶度透過構造方法建立會話後立即返回,此時的連線並沒有完全建立
    // 真正的會話建立完成後,zk服務端會給客戶端通知一個事件,客戶端獲取通知之後在表明連線正在建立。
    // 用於等待zk服務端通知
    private static CountDownLatch latch = new CountDownLatch(1);

    private static ZooKeeper zk = null;
    // 如果有多個地址,則使用逗號隔開
    private static final String connString="127.0.0.1:2181";
    // 超時時間
    private static final int sessionTimeout = 2000;

    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
        zk = new ZooKeeper(connString, sessionTimeout, new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                System.out.println("path = " + event.getPath() + ", eventType = " + event.getType() + ", keeperState = " + event.getState());
                if (Event.KeeperState.SyncConnected == event.getState()) {
                    latch.countDown();
                }
            }
        });
        latch.await();
        // 建立持久化節點
        String path1 = zk.create("/zk-data", "test-data".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        Stat stat1 = zk.exists("/zk-data", true);
        System.out.println(stat1);
        zk.delete("/zk-data",-1);
        Stat stat2 = zk.exists("/zk-data", false);
        System.out.println(stat2);
        // 關閉 zk
        zk.close();
    }
}
public byte[] getData(String path, boolean watch, Stat stat);
public byte[] getData(final String path, Watcher watcher, Stat stat);

public Stat exists(String path, boolean watch);
public Stat exists(final String path, Watcher watcher);

boolean watch:如果 watch 為 true,該 znode 的狀態變化會傳送給構建 Zookeeper 指定的 watcher

Watcher watcher:watcher 用來監聽該 znode 的狀態變化

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章