1. 程式人生 > >ZooKeeper完全解析(八) 使用Curator來簡化ZooKeeper操作之基本

ZooKeeper完全解析(八) 使用Curator來簡化ZooKeeper操作之基本

  在前幾篇中,我們講解了如何使用 Java ZooKeeper 庫來操作ZooKeeper,但是 Java ZooKeeper 庫只實現了ZooKeeper的一些基本操作,其餘分散式鎖,群首選舉等等,都沒有給出解決方法,那麼有沒有這麼一個庫來實現這些方案呢???答案是肯定的,就是我們今天要講的Curator。

一、引入Curator:

  curator有很多模組,核心的模組為
    curator-framework

  跟Spring-framowork-core類似,其它的模組有curator-client、curator-async等等,而我們只需要引入一個  
    curator-recipes 

  模組即可,curator-recipes 裡面包含了其它模組。

  因為我們的zooKeeper是 3.4.13 版本,所以  curator-recipes  也要使用 2.x.x 版本,如果使用更高版本會出現 
org.apache.zookeeper.KeeperException$UnimplementedException: KeeperErrorCode = Unimplemented for...
  錯誤

所以我的引入為:
        <!-- curator -->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>2.12.0</version>
        </dependency>

二、Curator中的增刪查改與時間監聽:

  ZooKeeper中的增刪查改,分別對應create、delete、(get,ls2,state)、set命令,那麼用Curator實現的程式碼為:

 1、連線ZooKeeper:

    // 重試策略
    RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
    CuratorFramework client = CuratorFrameworkFactory.newClient(env.getProperty("zookeeper.url"), retryPolicy);
    client.start();

 2、create:

    // 增加,對應命令  create
    client.create().withMode(CreateMode.PERSISTENT).forPath(curatorPath, "curator_data".getBytes());

 3、delete:

    // 刪
    client.delete().forPath(curatorPath + "/" + childList.get(0));
    List<String> childAfterList = client.getChildren().forPath(curatorPath);
    System.out.println(JSON.toJSONString("after : " + childAfterList));

 4、get與stat以及其時間監聽:

    // 監聽
    client.getData().usingWatcher((CuratorWatcher) e->{
                    if (e.getType() == Watcher.Event.EventType.NodeDataChanged) {
                        System.out.println("監聽資料更新  節點資料更新");
                    } else if (e.getType() == Watcher.Event.EventType.NodeDeleted) {
                        System.out.println("監聽資料更新  節點被刪除");
                    }
    }).forPath(curatorPath);
    client.getChildren().usingWatcher((CuratorWatcher) e->{
                    if (e.getType() == Watcher.Event.EventType.NodeChildrenChanged) {
                        System.out.println("監聽子節點更新  節點資料更新");
                    } 
    }).forPath(curatorPath);