zookeeper的Curator API

1 Curator API

CuratorFramework 是Netflix公司开发一款连接zookeeper服务的框架,提供了比较全面的功能,除了基础的节点的操作,节点的监听,还有集群的连接以及重试。

1.1 导入curator相关包
		<dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>2.10.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>2.10.0</version>
        </dependency>
1.2 导入springboot基础包
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
1.2 配置CuratorFramework客户端
package zookeeper.zk;

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.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ZookeeperConfig {

    @Value("${zookeeper.url}")
    private String zkUrl;

    @Bean
    public CuratorFramework getCuratorFramework() {
        /**
         * 同步创建zk实例,原生api是异步的
         *
         * curator链接zookeeper的策略:ExponentialBackoffRetry
         * baseSleepTimeMs: 初始sleep的时间
         * maxRetries: 最大重试次数
         * maxSleepMs: 最大重试时间
         */
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);

        /**
         * curator链接zookeeper的策略:RetryNTimes
         * n: 重试次数
         * sleepMsBetweenRetries: 每次重试间隔的时间
         */
        // RetryPolicy retryPolicya = new RetryNTimes(3, 5000);

        /**
         * curator链接zookeeper的策略: RetryOneTime
         * sleepMsBetweenRetry: 每次重试间隔的时间
         * 只重试一次  不推荐
         */
        //   RetryPolicy retryPolicyab = new RetryOneTime(3000);

        /**
         * 永远重试,不推荐使用
         */
        //  RetryPolicy retryPolicyac = new RetryForever(12);
        /**
         * curator链接zookeeper的策略: RetryUntilElapsed
         * maxElapsedTimeMs:最大重试时间
         * sleepMsBetweenRetries: 每次重试间隔
         * 重试时间超过maxElapsedTimeMs后,就不再重试
         */
        // RetryPolicy retryPolicyad = new RetryUntilElapsed(2000, 3000);

        CuratorFramework client = CuratorFrameworkFactory
                .builder()
               //登录用户List也可以 .authorization("digest", "ripper:123456".getBytes())
                .connectString(zkUrl)
                //会话时间必须大于心跳时间,不然会报错的
                .sessionTimeoutMs(20000)
                .retryPolicy(retryPolicy)
                //namespace表示站点-工作空间-客户端的名字-根节点
                .namespace("workspace")
                .build();

        client.start();
        return client;
    }
}

yml文件相关

zookeeper:
url: xxxxxxxxx,xxxxxxx //单机或者集群(逗号隔开)

1.3 curator API

1.3.1 创建节点

package zookeeper.test;

import org.apache.curator.framework.CuratorFramework;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class CuratorTest {

    @Autowired
    private CuratorFramework curatorFramework;
	
	/**
     * 创建节点类型,可自行尝试
     */
    @Test
    public void addnode() {
        try {
        	//节点路径
            String nodePath = "/ripper/addnode";
            //节点数据
            byte[] data = "format".getBytes();
            curatorFramework.create().creatingParentsIfNeeded()
            		// PERSISTENT普通节点  PERSISTENT_SEQUENTIAL顺序节点EPHEMERAL临时节点 EPHEMERAL_SEQUENTIAL临时顺序节点
                    .withMode(CreateMode.PERSISTENT)
                    //ACL后面会涉及
                    .withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE)
                    //定义节点名称和节点数据
                    .forPath(nodePath, data);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

创建节点
1.3.2 删除节点

	@Test
    public void deletenode() {
        try {
            String nodePath = "/super/imooc";
            curatorFramework.delete()
                    .guaranteed() //如果删除失败,后端还是会继续删除,直到成功
                    .deletingChildrenIfNeeded() //如果有子节点就删除
                    .withVersion(2) //根据版本号删除子节点
                    .forPath(nodePath);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

1.3.3 修改节点

	@Test
    public void updatenode() {
        try {
            String nodePath = "/ripper/updatenode";
            byte[] data = "format".getBytes();
            curatorFramework.setData()
                   .withVersion(2)
                    .forPath(nodePath, data);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

1.3.4 查询节点

	@Test
    public void querynode() {
        try {
        	// 节点数据对象
            Stat stat = new Stat();
            String nodePath = "/ripper/querynode";
            byte[] bytes = curatorFramework.getData()
                    .storingStatIn(stat)
                    .forPath(nodePath);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

1.3.5 监听(只会执行一次)

@Test
    public void watcher() {
        try {
            String nodePath = "/ripper/watcher";
            curatorFramework.getData()
                    //watcher只会触发一次,一次性的
                    .usingWatcher(new Watcher() {
                        @Override
                        public void process(WatchedEvent watchedEvent) {
                            System.out.println("监听触发");
                        }
                    }).forPath(nodePath);
            Thread.sleep(100000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

1.3.6 监听(永久生效)
nodeCache:对一个节点进行监听,监听事件包括指定的路径节点的增、删、改的操作。

@Test
    public void watcherforever() {
        try {
            String nodePath = "/ripper/watcherforever1";
            //删除节点的时候,nodeCache为null,空指针异常
            final NodeCache nodeCache = new NodeCache(curatorFramework, nodePath);
            //true 初始化的时候,获取node的值 并缓存
            nodeCache.start(true);
            nodeCache.getListenable().addListener(new NodeCacheListener() {
                @Override
                public void nodeChanged() throws Exception {
                    System.out.println("监听成功");
                }
            });
            Thread.sleep(100000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

1.3.7 监听(永久生效)
PathChildrenCache: 对指定的路径节点的一级子目录进行监听,不对该节点的操作进行监听,对其子目录的节点进行增、删、改的操作监听
TreeCache: 可以将指定的路径节点作为根节点(祖先节点),对其所有的子节点操作进行监听,呈现树形目录的监听,可以设置监听深度,最大监听深度为2147483647(int类型的最大值)。

@Test
    public void watcherchildenforever() {
        try {
            String nodePath = "/ripper/watcherchildenforever";
            //删除节点的时候,nodeCache为null,空指针异常
            final PathChildrenCache nodeCache = new PathChildrenCache(curatorFramework, nodePath, true);
            //BUILD_INITIAL_CACHE  同步   其他两种是异步
            nodeCache.start(PathChildrenCache.StartMode.BUILD_INITIAL_CACHE);
            nodeCache.getListenable().addListener(new PathChildrenCacheListener() {
                @Override
                public void childEvent(CuratorFramework curatorFramework, PathChildrenCacheEvent pathChildrenCacheEvent) throws Exception {
                    if(pathChildrenCacheEvent.getType().equals(PathChildrenCacheEvent.Type.INITIALIZED)){
                        System.out.println("初始化成功");
                    } else if(pathChildrenCacheEvent.getType().equals(PathChildrenCacheEvent.Type.CHILD_ADDED)){
                        System.out.println("添加节点");
                    } else if(pathChildrenCacheEvent.getType().equals(PathChildrenCacheEvent.Type.CHILD_UPDATED)){
                        System.out.println("子节点数据更改");
                    } else if(pathChildrenCacheEvent.getType().equals(PathChildrenCacheEvent.Type.CHILD_REMOVED)){
                        System.out.println("子节点被删除");
                    }
                }
            });
            Thread.sleep(100000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

1.3.8 ACL

	@Test
    public void acl() {
        try {
            String nodePath = "/ripper/acl";
            List<ACL> list = new ArrayList<>();
            Id ripper1 = new Id("digest", "ripper1:123456");
            Id ripper2 = new Id("digest", "ripper2:123456");
            list.add(new ACL(ZooDefs.Perms.ALL, ripper1));
            list.add(new ACL(ZooDefs.Perms.DELETE | ZooDefs.Perms.READ, ripper2));
            curatorFramework.setACL().withACL(list).forPath(nodePath);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值