@Slf4j
public class ZookeeperClientApi {
private static String ZK_ADDRESS = "zkServer:2181,zkServer:2182,zkServer:2183";
private static ZooKeeper ZK;
public static void main(String[] args) throws Exception{
// 初始化zk客戶端
initZookeeper(ZK_ADDRESS);
// 創建節點信息
createNode();
// 獲取節點信息
getData();
// 獲取子節點信息
getChildren();
// 刪除節點
deleteNode();
Thread.sleep(1000* 60*10);
}
/**
* TODO: 初始化zk
* * @param address
* @author zhijian.zheng
* @return org.apache.zookeeper.ZooKeeper
* @version 1.0
* @date 2019/8/15 上午9:51
*/
public static void initZookeeper(String address) throws Exception{
String connectString = address;
// 會話超時時間
int sessionTimeout = 3000;
log.error("zookeeper start connecting");
ZK = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent event) {
log.error("【事件被觸發了 --- 連接狀態:{},事件:{}】",event.getState(),event.getType());
}
});
log.error("zookeeper connection success!");
}
/**
* TODO: 創建節點
* @author zhijian.zheng
* @return void
* @version 1.0
* @date 2019/8/15 下午1:59
*/
public static void createNode() {
try {
if (ZK != null) {
// 1.1.創建持久化項目節點
log.error(ZK.create("/weixiu", "創建項目節點".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT));
// 1.2 創建臨時節點
log.error(ZK.create("/weixiu/repair", "維修模塊".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL));
// 1.3.創建持久化節點 異步
// new 回調對象
AsyncCallback.StringCallback stringCallback = new AsyncCallback.StringCallback() {
@Override
public void processResult(int i, String s, Object o, String s1) {
log.error("創建節點異步回調函數-{},{},{},{}",i,s,o,s1);
}
};
ZK.create("/weixiu/inspection", "環監模塊".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT,stringCallback,null);
// 1.4 父節點不存在時候,能否遞歸創建節點?
log.error(ZK.create("/weixiu01/repair", "維修模塊01".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL));
}
} catch (Exception e) {
log.error("【創建節點異常-{}】",e.getMessage());
}
}
/**
* TODO: 獲取節點信息(修改節點值)
* @author zhijian.zheng
* @return void
* @version 1.0
* @date 2019/8/15 上午11:10
*/
public static void getData(){
try {
log.error(new String(ZK.getData("/weixiu", new Watcher() {
// 一次性監聽
@Override
public void process(WatchedEvent event) {
log.error("【getData-節點數據變更監聽-state:{},type:{}】",event.getState(),event.getType());
}
}, new Stat())));
}catch (Exception e){
log.error("【獲取節點信息異常-{}】",e.getMessage());
}
}
/**
* TODO:獲取子節點信息 (創建子節點)
* @author zhijian.zheng
* @return void
* @version 1.0
* @date 2019/8/15 下午2:30
*/
public static void getChildren(){
try{
List<String> list = ZK.getChildren("/weixiu/inspection", new Watcher() {
@Override
public void process(WatchedEvent event) {
log.error("【getChildren-子節點數據變更監聽-state:{},type:{}】",event.getState(),event.getType());
}
},new Stat());
log.error(list.toString());
}catch (Exception e){
log.error("【獲取子節點信息異常-{}】",e.getMessage());
}
}
/**
* TODO:刪除節點信息
* @author zhijian.zheng
* @return void
* @version 1.0
* @date 2019/8/15 下午2:33
*/
public static void deleteNode(){
try{
ZK.delete("/zk03",-1);
ZK.delete("/zk02",-1);
}catch (Exception e){
log.error("【刪除節點異常-deleteNode-{}】",e.getMessage());
}
}
}
不足之處:
- Zookeeper的Watcher是一次性的,每次觸發之後都需要重新進行註冊;
- Session超時之後沒有實現重連機制;
- 異常處理繁瑣,Zookeeper提供了很多異常,對於開發人員來說可能根本不知道該如何處理這些異常信息;
- 只提供了簡單的byte[]數組的接口,沒有提供針對對象級別的序列化;
- 創建節點時如果節點存在拋出異常,需要自行檢查節點是否存在;
- 刪除節點無法實現級聯刪除;