<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型別,共有四種型別,如下所示
CreateMode.PERSISTENT:持久化節點,客戶端連線斷開後不會被自動刪除
CreateMode.PERSISTENT_SEQUENTIAL:持久化順序節點
CreateMode.EPHEMERAL:臨時節點,客戶端連線斷開後會被自動刪除
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 協議》,轉載必須註明作者和本文連結