zookeeper javaApi 事件監聽

1. 數據存儲

事務日誌
快照日誌
運行時日誌 bin/zookeeper.out

2 基於 Java API 初探 zookeeper 的使用

2.1 zookeeper 增刪改查

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;

import java.io.IOException;
import java.util.concurrent.CountDownLatch;

/**
 * @author: xiepanpan
 * @Date: 2020/5/30
 * @Description: zookeeper 連接
 */
public class ConnectionDemo {
    public static void main(String[] args) throws Exception {
        try {
            final CountDownLatch countDownLatch = new CountDownLatch(1);
            ZooKeeper zooKeeper =
                    new ZooKeeper("192.168.217.130:2181,192.168.217.130:2183,192.168.217.130:2183", 4000, new Watcher() {
                        public void process(WatchedEvent watchedEvent) {
                            //如果收到了服務端的響應事件,連接成功
                            if (Event.KeeperState.SyncConnected==watchedEvent.getState()) {
                                countDownLatch.countDown();
                            }
                        }
                    });
            countDownLatch.await();
            //CONNECTED
            System.out.println(zooKeeper.getState());

            //創建節點 第三個參數是權限 OPEN_ACL_UNSAFE 所有人都可以訪問 第四個參數 節點類型 持久節點
            zooKeeper.create("/zk-persistent-xpp","0".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            Thread.sleep(1000);

            //得到節點
            Stat stat = new Stat();
            byte[] bytes = zooKeeper.getData("/zk-persistent-xpp", null, stat);
            System.out.println(new String(bytes));

            //修改節點
            zooKeeper.setData("/zk-persistent-xpp","1".getBytes(),stat.getVersion());

            byte[] data = zooKeeper.getData("/zk-persistent-xpp", null, stat);
            System.out.println(new String(data));

            //刪除節點 使用樂觀鎖 比較版本號
            zooKeeper.delete("/zk-persistent-xpp",stat.getVersion());

            zooKeeper.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


2.2 事件機制

Watcher 監聽機制是 Zookeeper 中非常重要的特性,我們基於 zookeeper 上創建的節點,可以對這些節點綁定監聽
事件,比如可以監聽節點數據變更、節點刪除、子節點狀態變更等事件,通過這個事件機制,可以基於 zookeeper
實現分佈式鎖、集羣管理等功能
watcher 特性:當數據發生變化的時候, zookeeper 會產生一個 watcher 事件,並且會發送到客戶端。但是客戶端
只會收到一次通知。如果後續這個節點再次發生變化,那麼之前設置 watcher 的客戶端不會再次收到消息。(watcher 是一次性的操作)。 可以通過循環監聽去達到永久監聽效果

2.3 如何註冊事件機制

通過這三個操作來綁定事件 :getData、Exists、getChildren

2.4 如何觸發事件?

凡是事務類型的操作,都會觸發監聽事件。
create /delete /setData

2.5 watcher 事件類型

None (-1), 客戶端鏈接狀態發生變化的時候,會收到 none 的事件
NodeCreated (1), 創建節點的事件。 比如 zk-persis-mic
NodeDeleted (2), 刪除節點的事件
NodeDataChanged (3), 節點數據發生變更
NodeChildrenChanged (4); 子節點被創建、被刪除、會發生事件觸發

2.6 操作對應的water事件類型

zk-persis-mic ( 監聽事件) zk-persis-mic/child (子節點監聽事件)
create(/ zk-persis-mic) NodeCreated (exists getData)
delete(/ zk-persis-mic) NodeDeleted (exists getData)
setData(/ zk-persis-mic) NodeDataChanged (exists getData)
create(/ zk-persis-mic/child) NodeChildrenChange(getChildren) NodedCreated
delete(/ zk-persis-mic/child) NodeChildrenChange(getChildren) NodedDeleted
setData(/ zk-persis-mic/child) NodeDataChanged

3 Curator 客戶端的使用,簡單高效

3.1使用Curator對zookeeper增刪改查

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;

/**
 * @author: xiepanpan
 * @Date: 2020/5/31
 * @Description:  使用Curator框架來對zookeeper操作
 */
public class CuratorDemo {
    public static void main(String[] args) throws Exception {
        CuratorFramework curatorFramework = CuratorFrameworkFactory
                .builder()
                //衰減的重試機制
                .retryPolicy(new ExponentialBackoffRetry(1000,3))
                .connectString("192.168.217.130:2181,192.168.217.130:2183,192.168.217.130:2183")
                .sessionTimeoutMs(4000)
                //隔離命名空間  以下所有操作都是基於該相對目錄進行的
                .namespace("curator")
                .build();
        curatorFramework.start();

        //創建節點
        //結果 /curator/xpp/mode1
        curatorFramework.create()
                .creatingParentsIfNeeded()
                .withMode(CreateMode.PERSISTENT)
                .forPath("/xpp/node1","1".getBytes());

        //更改節點
        //保存節點狀態
        Stat stat = new Stat();
        curatorFramework.getData().storingStatIn(stat).forPath("/xpp/node1");
        curatorFramework.setData().withVersion(stat.getVersion()).forPath("/xpp/node1","xx".getBytes());

        //刪除節點
        curatorFramework.delete().deletingChildrenIfNeeded().forPath("/xpp/node1");
    }



}

3.2 監聽

PathChildrenCache 監聽一個節點下的子節點的創建刪除和更新

NodeCache監聽一個節點的更新和創建事件

TreeCache 綜合PathChildrenCache 和NodeCache 的特性

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.*;
import org.apache.curator.retry.ExponentialBackoffRetry;

/**
 * @author: xiepanpan
 * @Date: 2020/5/31
 * @Description:  事件監聽
 */
public class CuratorWatcherDemo {

    public static void main(String[] args) throws Exception {
        CuratorFramework curatorFramework = CuratorFrameworkFactory
                .builder()
                //衰減的重試機制
                .retryPolicy(new ExponentialBackoffRetry(1000,3))
                .connectString("192.168.217.130:2181,192.168.217.130:2183,192.168.217.130:2183")
                .sessionTimeoutMs(4000)
                //隔離命名空間  以下所有操作都是基於該相對目錄進行的
                .namespace("curator")
                .build();
        curatorFramework.start();

//        addListenerWithNodeCache(curatorFramework,"/xpp");
//        addListenerWithPathChildCache(curatorFramework,"/xpp");
        addListenerWithTreeCache(curatorFramework,"/xpp");
        System.in.read();
    }

    /**
     * 監聽一個節點的更新和創建事件
     * @param curatorFramework
     * @param path
     * @throws Exception
     */
    public static void addListenerWithNodeCache(CuratorFramework curatorFramework,String path) throws Exception {
        //第三個參數 對詳細內容數據的壓縮
        final NodeCache nodeCache = new NodeCache(curatorFramework,path,false);
        NodeCacheListener nodeCacheListener = new NodeCacheListener() {
            public void nodeChanged() throws Exception {
                System.out.println("Receive Event:"+nodeCache.getCurrentData().getPath());
            }
        };
        nodeCache.getListenable().addListener(nodeCacheListener);
        nodeCache.start();
    }

    /**
     *  監聽一個節點子節點的創建刪除和更新
     * @param curatorFramework
     * @param path
     * @throws Exception
     */
    public static void addListenerWithPathChildCache(CuratorFramework curatorFramework,String path) throws Exception {
        PathChildrenCache pathChildrenCache = new PathChildrenCache(curatorFramework, path, true);
        PathChildrenCacheListener pathChildrenCacheListener = new PathChildrenCacheListener() {
            public void childEvent(CuratorFramework curatorFramework, PathChildrenCacheEvent pathChildrenCacheEvent) throws Exception {
                System.out.println("Receive Event:"+pathChildrenCacheEvent.getType());
            }
        };
        pathChildrenCache.getListenable().addListener(pathChildrenCacheListener);
        pathChildrenCache.start(PathChildrenCache.StartMode.NORMAL);
    }

    /**
     * 綜合節點監聽事件 監聽當前節點和子節點  節點上任何一個事件都能收到
     * @param curatorFramework
     * @param path
     * @throws Exception
     */
    public static void addListenerWithTreeCache(CuratorFramework curatorFramework,String path) throws Exception {
        TreeCache treeCache = new TreeCache(curatorFramework,path);
        TreeCacheListener treeCacheListener = new TreeCacheListener() {
            public void childEvent(CuratorFramework curatorFramework, TreeCacheEvent treeCacheEvent) throws Exception {
                System.out.println(treeCacheEvent.getType()+"->"+treeCacheEvent.getData().getPath());
            }
        };
        treeCache.getListenable().addListener(treeCacheListener);
        treeCache.start();
    }
}

我的pom文件

<!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper -->
       <dependency>
           <groupId>org.apache.zookeeper</groupId>
           <artifactId>zookeeper</artifactId>
           <version>3.5.4-beta</version>
       </dependency>
       <!-- https://mvnrepository.com/artifact/org.apache.curator/curator-framework -->
       <dependency>
           <groupId>org.apache.curator</groupId>
           <artifactId>curator-framework</artifactId>
           <version>2.7.1</version>
       </dependency>
       <!-- https://mvnrepository.com/artifact/org.apache.curator/curator-recipes -->
       <dependency>
           <groupId>org.apache.curator</groupId>
           <artifactId>curator-recipes</artifactId>
           <version>2.7.1</version>
       </dependency>

zookeeper 我是用的3.4.14 版本
注意 Curator 版本 和zookeeper版本有對應關係 我的Curator版本是2.7.1

https://blog.csdn.net/glory1234work2115/article/details/51967507

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章