Apche curator操作zookeeper

常用的zookeeper java客户端

  • zk原生api

  • zkclient

  • Apache curator

原生api的不足之处

  • 超时重连,不支持自动,需要手动操作

  • Watch注册一次后会失效

  • 不支持递归创建节点

Apache curator

  • Apache的开源项目

  • 解决watcher的注册一次就失效的问题

  • Api更加简单易用

  • 提供更多解决方案并实现简单:例如分布式锁

  • 提供常用的zookeeper工具类

  • 编程风格更爽,调用方便

1.会话的连接与关闭

搭建maven工程,建立curator与zkserver的连接

添加maven依赖

<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-framework</artifactId>
    <version>4.0.0</version>
</dependency>

<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.4.11</version>
</dependency>

<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>4.0.0</version>
</dependency> 
建立curator与zkserver的连接
package com.zk.curator;
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.curator.retry.RetryUntilElapsed;
public class CuratorOperator {
public CuratorFramework client = null;
public static final String zkServePath = "192.168.119.129:2181";
/**
 * 实例化zk客户端
 */
public CuratorOperator() {
    /**
     * 同步创建zk实例,原生api是异步的
     * 
     * curator连接zookeeper的策略:ExponentialBackoffRetry
     * baseSleepTimeMs:初始sleep的时间
     * maxRetries:最大重试次数
     * maxSleepMs:最大重试时间
     * 推荐
     */

    RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 5);

    /**
     * curaotr连接zookeeper的策略:RetryNTimes
     * n:重试次数
     * sleepMsBetweenRetries
     * 推荐
     */

    //RetryNTimes retryPolicy = new RetryNTimes(3, 5000);

    /**
     * curator连接zookeeper的策略:RetryOneTime
     * sleepMsBetweenRetry:每次重试间隔的时间
     */
    //RetryOneTime retryPolicy = new RetryOneTime(3000);
    /**
     * 永远重试,不推荐使用
     */
    //RetryForever retryPolicy = new RetryForever(retryIntervalMs);


    /**
     * curator连接zookeeper的策略:RetryUntilElapsed
     * maxElapsedTimes:最大重试时间
     * sleepMsBetweenRetries:每次重试间隔
     * 重试时间超过maxElapsedTimeMs后就不在重试
     */

    //RetryUntilElapsed retryPolicy = new RetryUntilElapsed(2000, 3000);
    client = CuratorFrameworkFactory.builder()
    .connectString(zkServePath)
    .sessionTimeoutMs(10000).retryPolicy(retryPolicy)
    .build();
    client.start();

}


/**
 * 关闭zk客户端连接
 */

public void closeZKClient(){
    if(client != null){
        this.client.close();
    }
}

public static void main(String[] args) throws Exception {
    //实例化
    CuratorOperator cto = new CuratorOperator();
    boolean isZkCuratorStarted = cto.client.isStarted();
    System.out.println("当前客户端的状态:"+(isZkCuratorStarted?"连接中":"已关闭"));

    Thread.sleep(3000);

    cto.closeZKClient();
    boolean isZkCuratorStared2 = cto.client.isStarted();
    System.out.println("当前客户端的状态:"+(isZkCuratorStared2? "连接中":"已关闭"));
}
}
节点的增删改查
package com.zk.curator;
import java.util.List;
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.curator.retry.RetryUntilElapsed;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs.Ids
import org.apache.zookeeper.data.Stat;
public class CuratorOperator {
public CuratorFramework client = null;
public static final String zkServePath = "192.168.119.129:2181";
/**
 * 实例化zk客户端
 */
public CuratorOperator() {

    /**
     * 同步创建zk实例,原生api是异步的
     * 
     * curator连接zookeeper的策略:ExponentialBackoffRetry
     * baseSleepTimeMs:初始sleep的时间
     * maxRetries:最大重试次数
     * maxSleepMs:最大重试时间
     * 推荐
     */
    RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 5);
    /**
     * curaotr连接zookeeper的策略:RetryNTimes
     * n:重试次数
     * sleepMsBetweenRetries
     * 推荐
     */

    //RetryNTimes retryPolicy = new RetryNTimes(3, 5000);

    /**
     * curator连接zookeeper的策略:RetryOneTime
     * sleepMsBetweenRetry:每次重试间隔的时间
     */
    //RetryOneTime retryPolicy = new RetryOneTime(3000);
    /**
     * 永远重试,不推荐使用
     */
    //RetryForever retryPolicy = new RetryForever(retryIntervalMs);
    
    /**
     * curator连接zookeeper的策略:RetryUntilElapsed
     * maxElapsedTimes:最大重试时间
     * sleepMsBetweenRetries:每次重试间隔
     * 重试时间超过maxElapsedTimeMs后就不在重试
     */
    //RetryUntilElapsed retryPolicy = new RetryUntilElapsed(2000, 3000);        
    client = CuratorFrameworkFactory.builder()
    .connectString(zkServePath)
    .sessionTimeoutMs(10000).retryPolicy(retryPolicy)
    .namespace("workspace").build();
    client.start();
}

/**
 * 关闭zk客户端连接
 */
public void closeZKClient(){
    if(client != null){
        this.client.close();
    }
}    
public static void main(String[] args) throws Exception {
    //实例化
    CuratorOperator cto = new CuratorOperator();
    boolean isZkCuratorStarted = cto.client.isStarted();
    System.out.println("当前客户端的状态:"+(isZkCuratorStarted?"连接中":"已关闭"));
    
    //创建节点
    String nodePath = "/super/imooc";
//        byte[] data = "superme".getBytes();
//        cto.client.create().creatingParentsIfNeeded() //递归生成节点
//                           .withMode(CreateMode.PERSISTENT)
//                           .withACL(Ids.OPEN_ACL_UNSAFE)
//                           .forPath(nodePath,data);
        //更新节点数据
//        byte[] newData = "batman".getBytes();
//        cto.client.setData()
//                  .withVersion(0)
//                  .forPath(nodePath,newData);
           
        //删除节点
//        cto.client.delete()
//                  .guaranteed()
//                  .deletingChildrenIfNeeded()
//                  .withVersion(1)
//                  .forPath(nodePath);
 
    //读取节点
    Stat stat = new Stat();
    byte[] data = cto.client.getData().storingStatIn(stat).forPath(nodePath);
    System.out.println("节点"+nodePath+"的数据为:"+new String(data));
    System.out.println("改节点的版本号为:"+stat.getVersion());
    
    //查询子节点
    List<String> childNodes = cto.client.getChildren().forPath(nodePath);
    System.out.println("开始打印子节点:");
    for (String s : childNodes) {
        System.out.println(s);
    }
 
    //判断节点是否存在,如果不存在则为空
    Stat statExist = cto.client.checkExists().forPath(nodePath+"/abc");
    System.out.println(statExist);    
    Thread.sleep(3000);

   

    cto.closeZKClient();
    boolean isZkCuratorStared2 = cto.client.isStarted();
    System.out.println("当前客户端的状态:"+(isZkCuratorStared2? "连接中":"已关闭"));
}
}
watch与acl的相关操作
package com.zk.curator;
import java.util.List; 
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.ChildData;
import org.apache.curator.framework.recipes.cache.NodeCache;
import org.apache.curator.framework.recipes.cache.NodeCacheListener;
import org.apache.curator.framework.recipes.cache.PathChildrenCache;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
import org.apache.curator.framework.recipes.cache.PathChildrenCache.StartMode;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.retry.RetryUntilElapsed;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.data.Stat;

/**
 * curator操作zookeeper节点的增删改查
 * @author 33193
 *
 */
public class CuratorWatcher {

public CuratorFramework client = null;
public static final String zkServePath = "192.168.119.129:2181";    

/**
 * 实例化zk客户端
 */

public CuratorWatcher() {
    /**
     * 同步创建zk实例,原生api是异步的
     * curator连接zookeeper的策略:ExponentialBackoffRetry
     * baseSleepTimeMs:初始sleep的时间
     * maxRetries:最大重试次数
     * maxSleepMs:最大重试时间
     * 推荐
     */

    RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 5);
    
    /**
     * curaotr连接zookeeper的策略:RetryNTimes
     * n:重试次数
     * sleepMsBetweenRetries
     * 推荐
     */

    //RetryNTimes retryPolicy = new RetryNTimes(3, 5000);
   
    /**
     * curator连接zookeeper的策略:RetryOneTime
     * sleepMsBetweenRetry:每次重试间隔的时间
     */

    //RetryOneTime retryPolicy = new RetryOneTime(3000);
   
    /**
      * 永远重试,不推荐使用
     */

    //RetryForever retryPolicy = new RetryForever(retryIntervalMs);
   
    /**
     * curator连接zookeeper的策略:RetryUntilElapsed
     * maxElapsedTimes:最大重试时间
     * sleepMsBetweenRetries:每次重试间隔
     * 重试时间超过maxElapsedTimeMs后就不在重试
     */

    //RetryUntilElapsed retryPolicy = new RetryUntilElapsed(2000, 3000);
      client = CuratorFrameworkFactory.builder()
    .connectString(zkServePath)
    .sessionTimeoutMs(10000).retryPolicy(retryPolicy)
    .namespace("workspace").build();
    client.start();
}



/**
 * 关闭zk客户端连接
 */
public void closeZKClient(){
    if(client != null){
        this.client.close();
    }
}

public static void main(String[] args) throws Exception {
    //实例化
    CuratorWatcher cto = new CuratorWatcher();
    boolean isZkCuratorStarted = cto.client.isStarted();
    System.out.println("当前客户端的状态:"+(isZkCuratorStarted?"连接中":"已关闭"));
 
    String nodePath = "/super/imooc";       
    
    //watcher事件 当使用usingWatcher的时候,监听只会触发一次,监听完毕后就销毁
//        cto.client.getData().usingWatcher(new MyCuratorWatcher()).forPath(nodePath);
//        cto.client.getData().usingWatcher(new MyWatcher()).forPath(nodePath);        

    /**
     * 一次注册N次监听
     */
    //为节点添加watcher
    //NodeCache:监听数据节点的变更,会触发事件
    final NodeCache nodeCache = new NodeCache(cto.client, nodePath);
    //buildInitial:初始化的时候获取node的值并且缓存
    nodeCache.start(true);
    if(nodeCache.getCurrentData() != null){
        System.out.println("节点的初始化数据为:"+new String(nodeCache.getCurrentData().getData()));
    }else{
        System.out.println("节点初始化数据为空...");
    }
    
    //监听器
    nodeCache.getListenable().addListener(new NodeCacheListener() {
  
        public void nodeChanged() throws Exception {
            String data = new String(nodeCache.getCurrentData().getData());
            System.out.println("节点路径:"+nodeCache.getCurrentData().getPath()+"数据"+data);
        }
    });        

    //为子节点添加watcher
    //PathChildrenCache:监听数据节点的增删改,会触发事件
    String childNodePathCache = nodePath;
    PathChildrenCache childrenCache = new PathChildrenCache(cto.client, childNodePathCache, true);

    /**
     * StartMode:初始化方式
     * POST_INITIALIZED_EVENT:异步初始化,初始化之后会触发事件
     * NORMAL:异步初始化
     * BUILD_INITIAL_CACHE:同步初始化
     */

    childrenCache.start(StartMode.POST_INITIALIZED_EVENT);       
    List<ChildData> childDataList = childrenCache.getCurrentData();
    System.out.println("当前数据节点的子节点数据列表:");
    for (ChildData cd : childDataList) {
        String childData = new String(cd.getData());
        System.out.println(childData);
    }
   
    childrenCache.getListenable().addListener(new PathChildrenCacheListener() {           
        public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
            if(event.getType().equals(PathChildrenCacheEvent.Type.INITIALIZED)){
                System.out.println("子节点初始化ok");
            }else if(event.getType().equals(PathChildrenCacheEvent.Type.CHILD_ADDED)){
                System.out.println("添加子节点:"+event.getData().getPath());
                System.out.println("子节点数据:"+new String(event.getData().getData()));
            }else if(event.getType().equals(PathChildrenCacheEvent.Type.CHILD_REMOVED)){
                System.out.println("删除子节点:"+event.getData().getPath());
            }else if(event.getType().equals(PathChildrenCacheEvent.Type.CHILD_UPDATED)){
                System.out.println("修改子节点:"+event.getData().getPath());
                System.out.println("修改点数据:"+new String(event.getData().getData()));
            }
        }
    });
   
    Thread.sleep(3000);       
    
    cto.closeZKClient();
    boolean isZkCuratorStared2 = cto.client.isStarted();
    System.out.println("当前客户端的状态:"+(isZkCuratorStared2? "连接中":"已关闭"));
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值