• curator操作zookeeper


    使用zookeeper原生API实现一些复杂的东西比较麻烦。所以,出现了两款比较好的开源客户端,对zookeeper的原生API进行了包装:zkClient和curator。后者是Netflix出版的,必属精品,也是最好用的zk的开源客户端。

    一  curator基本API使用

    推荐博客:https://www.cnblogs.com/java-zhao/p/7350945.html

    https://www.cnblogs.com/nevermorewang/p/5815602.html    强烈推荐

    pom

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

    创建客户端

    private static CuratorFramework client = CuratorFrameworkFactory.builder()
           .authorization("digest","admin:123".getBytes()) //创建客户端的时候授权 .connectString(
    "ip:2181") .sessionTimeoutMs(50000) .connectionTimeoutMs(30000) .retryPolicy(new ExponentialBackoffRetry(1000, 3)).build();

    创建节点

          /**
              * 创建会话
              */
             client.start();
     
             /**
              * 创建节点
              * 注意:
              * 1 除非指明创建节点的类型,默认是持久节点
              * 2 ZooKeeper规定:所有非叶子节点都是持久节点,所以递归创建出来的节点,只有最后的数据节点才是指定类型的节点,其父节点是持久节点
              */
             client.create().forPath("/China");//创建一个初始内容为空的节点
             client.create().forPath("/America", "zhangsan".getBytes());
             client.create().withMode(CreateMode.EPHEMERAL).forPath("/France");//创建一个初始内容为空的临时节点
             client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath("/Russia/car", "haha".getBytes());//递归创建,/Russia是持久节点
             
             
             /**
              * 异步创建节点
              * 注意:如果自己指定了线程池,那么相应的操作就会在线程池中执行,如果没有指定,那么就会使用Zookeeper的EventThread线程对事件进行串行处理
              */
             client.create().withMode(CreateMode.EPHEMERAL).inBackground(new BackgroundCallback() {
                 @Override
                 public void processResult(CuratorFramework client, CuratorEvent event) throws Exception {
                     System.out.println("当前线程:" + Thread.currentThread().getName() + ",code:" + event.getResultCode()
                                        + ",type:" + event.getType());
                 }
             }, Executors.newFixedThreadPool(10)).forPath("/async-curator-my");
     
             client.create().withMode(CreateMode.EPHEMERAL).inBackground(new BackgroundCallback() {
                 @Override
                 public void processResult(CuratorFramework client, CuratorEvent event) throws Exception {
                     System.out.println("当前线程:" + Thread.currentThread().getName() + ",code:" + event.getResultCode()
                                        + ",type:" + event.getType());
                 }
             }).forPath("/async-curator-zookeeper");

    获取节点数据

    Stat stat = new Stat();
    byte[] bytes = zk.curator.getData().storingStatIn(stat).forPath("/liuzhonghua");
    System.out.println("路径/liuzhonghua的数据是:"+new String(bytes));
    System.out.println("路径/liuzhonghua的数据的版本是:"+stat.getVersion());

     路径/liuzhonghua的数据是:lzh
     路径/liuzhonghua的数据的版本是:0

    更新节点

    client.setData().withVersion(4).forPath("/America", "lisi".getBytes());

    删除节点

          /**
              * 删除节点
              */
             client.delete().forPath("/China");//只能删除叶子节点
             client.delete().deletingChildrenIfNeeded().forPath("/Russia");//删除一个节点,并递归删除其所有子节点
             client.delete().withVersion(5).forPath("/America");//强制指定版本进行删除
             client.delete().guaranteed().forPath("/America");//注意:由于一些网络原因,上述的删除操作有可能失败,使用guaranteed(),如果删除失败,会记录下来,只要会话有效,就会不断的重试,直到删除成功为止
        

    创建Acl权限

            ArrayList<ACL> acls = new ArrayList<ACL>();
            Id id1=new Id("digest", DigestAuthenticationProvider.generateDigest("admin1:123"));
            Id id2=new Id("digest", DigestAuthenticationProvider.generateDigest("admin2:123"));
            acls.add(new ACL(ZooDefs.Perms.ADMIN,id1));
            acls.add(new ACL(ZooDefs.Perms.CREATE,id2));
            acls.add(new ACL(ZooDefs.Perms.ADMIN | ZooDefs.Perms.READ,id2));
            zk.curator.create().creatingParentsIfNeeded().withACL(acls).forPath("/liuzhonghua001/003","lzh".getBytes());

    结果:

    [zk: localhost:2181(CONNECTED) 5] getAcl /liuzhonghua001/003
    'digest,'admin1:CC9El/l/qyakTrK/mNREkrSikQ0=
    : a
    'digest,'admin2:iZICqg+4cn1ouEHqGPuzGrop/M4=
    : c
    'digest,'admin2:iZICqg+4cn1ouEHqGPuzGrop/M4=
    : ra
    [zk: localhost:2181(CONNECTED) 6]

     设置Acl权限

     ArrayList<ACL> acls = new ArrayList<ACL>();
            Id id1=new Id("digest", DigestAuthenticationProvider.generateDigest("admin1:123"));
            Id id2=new Id("digest", DigestAuthenticationProvider.generateDigest("admin2:123"));
            acls.add(new ACL(ZooDefs.Perms.ADMIN,id1));
            acls.add(new ACL(ZooDefs.Perms.CREATE,id2));
            acls.add(new ACL(ZooDefs.Perms.ADMIN | ZooDefs.Perms.READ,id2));
    
    zk.curator.setACL().withACL(acls).forPath("/liuzhonghua001/003");

    curator实现事件监听

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

    对指定节点进行监听(监听指定节点本身的变化,包括节点本身的创建和节点本身数据的变化)

    NodeCache nodeCache = new NodeCache(client,"/lzh");
            nodeCache.getListenable().addListener(new NodeCacheListener() {
                                                      @Override
                                                      public void nodeChanged() throws Exception {
                                                          System.out.println("新的节点数据:" + new String(nodeCache.getCurrentData().getData()));
                                                      }
                                                  });
    nodeCache.start(true);

    监听子节点变化情况(1 新增子节点,2删除子节点,3数据改变)

    /**
             * 监听子节点变化情况
             * 1 新增子节点
             * 2 删除子节点
             * 3 子节点数据变更
             */
            PathChildrenCache pathChildrenCache = new PathChildrenCache(client,"/lzh",true);
            pathChildrenCache.getListenable().addListener(new PathChildrenCacheListener() {
                @Override
                public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
                    switch (event.getType()){
                        case CHILD_ADDED:
                            System.out.println("新增子节点:" + event.getData().getPath());
                            break;
                        case CHILD_UPDATED:
                            System.out.println("子节点数据变化:" + event.getData().getPath());
                            break;
                        case CHILD_REMOVED:
                            System.out.println("删除子节点:" + event.getData().getPath());
                            break;
                        default:
                            break;
                    }
                }
            });
            pathChildrenCache.start();
    • PathChildrenCache只会监听指定节点的一级子节点,不会监听节点本身(例如:“/book13”),也不会监听子节点的子节点(例如,“/book13/car/color”)
  • 相关阅读:
    Spring基础篇——AOP切面编程
    像我这样的人
    Java 内部类
    SQLite 带你入门
    Spring基础篇——通过Java注解和XML配置装配bean
    Spring基础篇——自动化装配bean
    VMware虚拟机+CentOS系统安装
    Spring基础篇——Spring容器和应用上下文理解
    Spring基础篇——DI/IOC和AOP原理初识
    Web 项目刚要打包,却找不到项目资源?
  • 原文地址:https://www.cnblogs.com/coder-lzh/p/9523297.html
Copyright © 2020-2023  润新知