Zookeeper Curator常用API实例

  1. 引入Zookeeper
   <!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper -->
    <dependency>
      <groupId>org.apache.zookeeper</groupId>
      <artifactId>zookeeper</artifactId>
      <version>3.6.3</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.apache.curator/curator-recipes -->
    <dependency>
      <groupId>org.apache.curator</groupId>
      <artifactId>curator-recipes</artifactId>
      <version>4.0.1</version>
    </dependency>
  1. 创建节点
/**
3. curator
4. 创建节点
5. 作者:负差生
6. 时间:2021年6月3日13:36:46
*/
public class CreateNodeDemo {
   /** 重试策略:重试间隔时间为1000ms; 最多重试3次; */
   private static RetryPolicy retryPolicy = new RetryNTimes(3, 1000);
   private static ZooKeeper zooKeeper;
   public static void main(String[] args) throws Exception {
       //建立链接
       //connectString:链接地址
       //sessionTimeoutMs:会话超时时间
       //connectTimeoutMs:链接超时间、
       //重试策略
       CuratorFramework curatorFramework = CuratorFrameworkFactory.newClient("localhost:2181", 5000,
               5000, retryPolicy);
       //建立链接
       curatorFramework.start();
       // 其中creatingParentsIfNeeded()的作用为:如果要创建的节点的父节点不存在,那么会先创建父节点,再创建该节点
       String newNode = curatorFramework
               .create()
               .creatingParentsIfNeeded()
               .withMode(CreateMode.PERSISTENT)
               .forPath("/a_node/a_1", "".getBytes());
       System.out.println("新创建的节点是:" + newNode);
   }
}

测试
在这里插入图片描述

  1. 删除节点
**
8. curator
9. 创建节点
10. 作者:负差生
11. 时间:20216313:36:46
*/
public class DeleteNodeDemo {
   /** 重试策略:重试间隔时间为1000ms; 最多重试3次; */
   private static RetryPolicy retryPolicy = new RetryNTimes(3, 1000);

   public static void main(String[] args) throws Exception {
       CuratorFramework curator = CuratorFrameworkFactory.newClient("localhost:2181", 5000, 5000, retryPolicy);
       curator.start();
       // 删除(无子节点的)节点
       //client.delete().forPath("/a_node");
       // 删除指定版本的(无子节点的)节点
       //client.delete().withVersion(4).forPath("/a_node");
       // 删除节点(如果有子节点,也一并删除)
       curator.delete().deletingChildrenIfNeeded().forPath("/a_node");
       // 删除指定版本的节点(如果有子节点,也一并删除)
       //client.delete().deletingChildrenIfNeeded().withVersion(4).forPath("/a_node");
       // 只要Session有效,那么就会对指定节点进行持续删除,直到删除成功; 这是一种保障机制
       //client.delete().guaranteed().deletingChildrenIfNeeded().withVersion(4).forPath("/a_node");
   }
}

在这里插入图片描述

  1. . 获取节点数据
        // 获取节点的数据的同时,并将节点状态信息放入传入的stat实例中
        Stat stat = new Stat();
        //获取数据信息
        byte[] data = client.getData().storingStatIn(stat).forPath("/");
        //转为string
        System.out.println("节点“/”的数据内容为:" + new String(data));
        System.out.println("节点“/”的stat状态信息为:" + stat);
  1. 重置节点
public class SetDemo {
    /** 重试策略:重试间隔时间为1000ms; 最多重试3次; */
    private static RetryPolicy retryPolicy = new RetryNTimes(3, 1000);
    public static void main(String[] args) throws Exception {
        CuratorFramework curator = CuratorFrameworkFactory.newClient("localhost:2021", 5000, 5000,
                retryPolicy);
        curator.start();

        // 设置节点数据
        // client.setData().forPath("/", "我是修改后的节点数据内容".getBytes());

        // 先获取到节点的状态
        Stat statOne = new Stat();
        curator.getData().storingStatIn(statOne).forPath("/");
        System.out.println("修改节点“/”的数据后,数据版本为:" + statOne.getVersion());
        // 设置节点数据(校验版本信息)
        Stat statTwo = curator.setData().withVersion(statOne.getVersion()).forPath("/", "我是修改后的节点数据内容".getBytes());
        System.out.println("修改节点“/”的数据后,数据版本为:" + statTwo.getVersion());
    }
}
  1. 判断节点存在
        Stat stat = client.checkExists().forPath("/");
        System.out.println(stat == null ? "节点不存在!" : "节点存在!");
  1. 获取子节点
   List<String> children = client.getChildren().forPath("/");
        System.out.println("节点“/”的子节点集合:" + children);
  1. 设置权限
 // ID白名单模式,给ip为localhost的客户端分配所有权限
        ACL aclIdOne = new ACL(ZooDefs.Perms.ALL, new Id("ip", "localhost"));
        // ID白名单模式,给ip为10.8.109.76的客户端分配 读 的权限
        ACL aclIdTwo = new ACL(ZooDefs.Perms.READ, new Id("ip", "10.8.109.76"));
        // ID白名单模式,给ip为localhost的客户端分配 读和写 的权限
        ACL aclIdThree = new ACL(ZooDefs.Perms.READ | ZooDefs.Perms.WRITE, new Id("ip", "10.8.109.44"));
        // 用户名密码模式,设置userOne用户,有所有权限
        ACL aclDigestOne = new ACL(ZooDefs.Perms.ALL, new Id("digest", DigestAuthenticationProvider.generateDigest("userOne:123")));
        // 用户名密码模式,设置userTwo用户,有 读 权限
        ACL aclDigestTwo = new ACL(ZooDefs.Perms.READ, new Id("digest", DigestAuthenticationProvider.generateDigest("userTwo:123")));
        // 用户名密码模式,设置userThree用户,有 读和写 权限
        ACL aclDigestThree = new ACL(ZooDefs.Perms.READ | ZooDefs.Perms.WRITE, new Id("digest", DigestAuthenticationProvider.generateDigest("userThree:123")));
        List<ACL> acls = new ArrayList<>(8);
        acls.add(aclIdOne);
        acls.add(aclIdTwo);
        acls.add(aclIdThree);
        acls.add(aclDigestOne);
        acls.add(aclDigestTwo);
        acls.add(aclDigestThree);

        // 其中creatingParentsIfNeeded()的作用为:如果要创建的节点的父节点不存在,那么会先创建父节点,再创建该节点
        String newNode = client
                .create()
                .creatingParentsIfNeeded()
                .withMode(CreateMode.PERSISTENT)
                .withACL(acls)
                .forPath("/auth_node", "".getBytes());
        System.out.println("新创建的节点是:" + newNode);
  1. 添加监听
        //client客户端
        //监听节点位置
        //最后一个参数为true,表示出节点内容外还监听缓存内容
        final PathChildrenCache cache = new PathChildrenCache(client,"/", true);
        // 开始监听
        //如果路径下存在原始节点,则设置参数,否则会将元节点当新节点发送event
         cache.start(PathChildrenCache.StartMode.BUILD_INITIAL_CACHE);
        // 当目标节点的子节点被创建、子节点被删除、子节点数据内容发生变化等时,会触发监听方法
        cache.getListenable().addListener(new PathChildrenCacheListener() {

            @Override
            public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
                System.out.println("线程" + Thread.currentThread().getName() + "说,进入监听方法了!");
                byte[] data;
                switch (event.getType()){
                    case CHILD_ADDED :
                        System.out.println("新增子节点!");
                        System.out.println("子节点path为:" + event.getData().getPath());
                        System.out.println("子节点Stat为:" + event.getData().getStat());
                        data = event.getData().getData();
                        System.out.println("子节点数据内容为:" + (data == null ? null : new String(data)));
                        break;
                    case  CHILD_REMOVED :
                        System.out.println("删除子节点!");
                        System.out.println("子节点path为:" + event.getData().getPath());
                        System.out.println("子节点Stat为:" + event.getData().getStat());
                        data = event.getData().getData();
                        System.out.println("子节点数据内容为:" + (data == null ? null : new String(data)));
                        break;
                    case CHILD_UPDATED :
                        System.out.println("修改子节点数据内容!");
                        System.out.println("子节点path为:" + event.getData().getPath());
                        System.out.println("子节点Stat为:" + event.getData().getStat());
                        data = event.getData().getData();
                        System.out.println("子节点数据内容为:" + (data == null ? null : new String(data)));
                        break;
                    default :
                        System.out.println("default!");
                }
            }
        });

在这里插入图片描述在这里插入图片描述
11. 异步调用示例(以创建节点数据示例)

public class AsyncDemo {

    /** 重试策略:重试间隔时间为1000ms; 最多重试3次; */
    private static RetryPolicy retryPolicy = new RetryNTimes(3, 1000);

    /**
     * 实现异步调用接口
     */
    private static class MyBackgroundCallback implements BackgroundCallback {

        @Override
        public void processResult(CuratorFramework client, CuratorEvent event) throws Exception {
            System.out.println("进入回调方法了!执行此方法的线程是:" + Thread.currentThread().getName());
            StringBuilder sb = new StringBuilder(64);
            sb.append("操作事件类型CuratorEventType为:").append(event.getType()).append("\n");
            sb.append("ACL为:").append(event.getACLList()).append("\n");
            sb.append("子节点集合为:").append(event.getChildren()).append("\n");
            sb.append("操作时传入的上下文数据:").append(event.getContext()).append("\n");
            sb.append("所操作节点(操作进行前)为:").append(event.getPath()).append("\n");
            byte[] data = event.getData();
            sb.append("所操作节点数据内容为:").append(data == null ? null : new String(data)).append("\n");
            // 当节点类型为  有序节点时,path与name不一致
            sb.append("所操作节点(操作进行后)为:").append(event.getName()).append("\n");
            // 操作成功的结果码为0
            sb.append("操作结果码为:").append(event.getResultCode()).append("\n");
            sb.append("所操作节点stat为:").append(event.getStat()).append("\n");
            sb.append("WatchedEvent为:").append(event.getWatchedEvent());
            System.out.println(sb.toString());
        }
    }

    public static void main(String[] args) throws Exception {
        CuratorFramework client = CuratorFrameworkFactory.newClient("localhost:2181",5000,
                5000, retryPolicy);
        // 启动客户端
        client.start();


        /*
         异步创建节点
         注:inBackground有多个重载方法;根据实际情况选择适合的即可
         注:执行回调函数的是一个单独的线程;如果同一时刻回调函数较多的话,我们就可以考虑引入线程池(不引入的话,频繁的创建销毁线程会比较耗性能)
            inBackground(BackgroundCallback callback, Object context, Executor executor);
             .withMode(CreateMode.PERSISTENT_SEQUENTIAL)设置是否是带有自增ID
        */
        client.create()
                .withMode(CreateMode.PERSISTENT_SEQUENTIAL)
                .inBackground(new MyBackgroundCallback(), "我是上下文Object数据")
                .forPath("/abc", "异步创建节点".getBytes());


        // 为了看见控制台输出,我们不能让main线程死得太早
        TimeUnit.MILLISECONDS.sleep(10000);
    }

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值