github: https://github.com/zhaikaishun/zookeeper_tutorial
前言
Zookeeper的原生API,就之前的那一些,用起來還是比較麻煩的,所以,有些工程師對原生的API接口進行了封裝,簡化了ZK的複雜性。
- 創建客戶端的方法: ZKClient(Arguments)
- 參數1:zkServer zookeeper服務器的地址,用","分割
- 參數2:sessionTimeout超時回話,爲毫秒,默認是30000ms
- 參數3:connectionTimeOut 連接超時會話
- 參數4:IZKConnection接口的實現類
- 參數5:zkSerializer 茲定於序列化實現
需要引入zkclient的jar包,自行百度即可
ZKClient的基礎操作
ZKClient建立連接
直接new即可
String CONNECT_ADDR = "192.168.1.171:2181,192.168.1.172:2181,192.168.1.173:2181";
ZkClient zkc = new ZkClient(new ZkConnection(CONNECT_ADDR), 10000);
ZKClient創建節點
方法1 和原生的差不多
zkc.create(final String path, Object data, final CreateMode mode)
方法2
zkc.createEphemeral("/temp");
// 可以支持遞歸的創建,但是不能遞歸賦值
zkc.createPersistent("/super/c1", true);
刪除節點的操作
支持遞歸的刪除
刪除 /temp節點
zkc.delete("/temp");
//遞歸刪除/super
zkc.deleteRecursive("/super");
獲取子節點和閱讀節點內容操作
List<String> list = zkc.getChildren("/super");
for(String p : list){
System.out.println(p);
String rp = "/super/" + p;
String data = zkc.readData(rp);
System.out.println("節點爲:" + rp + ",內容爲: " + data);
}
更新節點
zkc.writeData("/super/c1", "新內容");
一個簡單的例子
代碼在 bjsxt.zkclient.base
public class ZkClientBase {
/** zookeeper地址 */
static final String CONNECT_ADDR = "192.168.1.31:2181,192.168.1.32:2181,192.168.1.33:2181";
/** session超時時間 */
static final int SESSION_OUTTIME = 10000;//ms
public static void main(String[] args) throws Exception {
ZkClient zkc = new ZkClient(new ZkConnection(CONNECT_ADDR), SESSION_OUTTIME);
//1. create and delete方法
zkc.createEphemeral("/temp");
zkc.createPersistent("/super/c1", true);
Thread.sleep(10000);
zkc.delete("/temp");
zkc.deleteRecursive("/super");
//2. 設置path和data 並且讀取子節點和每個節點的內容
zkc.createPersistent("/super", "1234");
zkc.createPersistent("/super/c1", "c1內容");
zkc.createPersistent("/super/c2", "c2內容");
List<String> list = zkc.getChildren("/super");
for(String p : list){
System.out.println(p);
String rp = "/super/" + p;
String data = zkc.readData(rp);
System.out.println("節點爲:" + rp + ",內容爲: " + data);
}
//3. 更新和判斷節點是否存在
zkc.writeData("/super/c1", "新內容");
System.out.println(zkc.readData("/super/c1").toString());
System.out.println(zkc.exists("/super/c1"));
// 4.遞歸刪除/super內容
zkc.deleteRecursive("/super");
}
}
輸出
c1
節點爲:/super/c1,內容爲: c1內容
c2
節點爲:/super/c2,內容爲: c2內容
新內容
true
ZKClient Watch的使用
我們發現,上述ZKClient裏面並沒有類似的watcher、watch參數,這也就是說我們開發人員無需關心反覆註冊watcher的問題,zkclient給我們提供了一套監聽方式,我們可以使用監聽節點的方式進行操作,剔除了繁瑣的反覆watcher操作、簡化了代碼的複雜程度
subscribeChildChanges方法 訂閱子節點變化
參數1:path路徑
參數2:實現了IZKChildListener接口的類(如:實例化IZKClientListener類) 只需要重寫其handleChildChanges(String parentPath, List currentChild)方法。其中
- parentPath 爲監聽節點全路徑
- currentChilds爲新的子節點列表
IZKChildListener事件說明針對於下面三個事件觸發: - 新增子節點
- 減少子節點
- 刪除節點
注意: 不監聽節點內容的變化
舉例
public class ZkClientWatcher1 {
/** zookeeper地址 */
static final String CONNECT_ADDR = "192.168.1.31:2181,192.168.1.32:2181,192.168.1.33:2181";
/** session超時時間 */
static final int SESSION_OUTTIME = 10000;//ms
public static void main(String[] args) throws Exception {
ZkClient zkc = new ZkClient(new ZkConnection(CONNECT_ADDR), SESSION_OUTTIME);
//對父節點添加監聽子節點變化。
zkc.subscribeChildChanges("/super", new IZkChildListener() {
@Override
public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception {
System.out.println("parentPath: " + parentPath);
System.out.println("currentChilds: " + currentChilds);
}
});
Thread.sleep(3000);
zkc.createPersistent("/super");
Thread.sleep(1000);
zkc.createPersistent("/super" + "/" + "c1", "c1內容");
Thread.sleep(1000);
zkc.createPersistent("/super" + "/" + "c2", "c2內容");
Thread.sleep(1000);
zkc.delete("/super/c2");
Thread.sleep(1000);
zkc.deleteRecursive("/super");
Thread.sleep(Integer.MAX_VALUE);
}
}
輸出
parentPath: /super
currentChilds: []
parentPath: /super
currentChilds: [c1]
parentPath: /super
currentChilds: [c1, c2]
parentPath: /super
currentChilds: [c1]
parentPath: /super
currentChilds: null
parentPath: /super
currentChilds: null
subscribeDataChanges 訂閱內容變化
和前面的subscribeChildChanges類似
- 參數1 路徑
- 參數2 IZkDataListener對象,重寫handleDataDeleted(String path) 方法,可以得到刪除節點的path 重寫handleDataChange(String path, Object data)可以得到變更的節點和變更的內容
舉例
public class ZkClientWatcher2 {
/** zookeeper地址 */
static final String CONNECT_ADDR = "192.168.1.31:2181,192.168.1.32:2181,192.168.1.33:2181";
/** session超時時間 */
static final int SESSION_OUTTIME = 10000;//ms
public static void main(String[] args) throws Exception {
ZkClient zkc = new ZkClient(new ZkConnection(CONNECT_ADDR), SESSION_OUTTIME);
zkc.createPersistent("/super", "1234");
//對父節點添加監聽子節點變化。
zkc.subscribeDataChanges("/super", new IZkDataListener() {
@Override
public void handleDataDeleted(String path) throws Exception {
System.out.println("刪除的節點爲:" + path);
}
@Override
public void handleDataChange(String path, Object data) throws Exception {
System.out.println("變更的節點爲:" + path + ", 變更內容爲:" + data);
}
});
Thread.sleep(3000);
zkc.writeData("/super", "456", -1);
Thread.sleep(1000);
zkc.delete("/super");
Thread.sleep(Integer.MAX_VALUE);
}
}
輸出
變更的節點爲:/super, 變更內容爲:456
刪除的節點爲:/super
筆者主要是記錄筆記,以便之後翻閱,正所謂好記性不如爛筆頭,爛筆頭不如雲筆記