zookeeper学习四-Curator客户端

1 Curator客户端简介

curator是netflix公司开源的一个zk客户端,后捐赠给apache。curator框架在原生的zk api上进行了封装,隐藏了很多zookeeper客户端底层的细节,提供了zookeeper各种应用场景(分布式锁、集群领导选举、共享计数器、缓存机制、分布式队列)的抽象封装,实现了链式风格编码,是最流行的zookeeper客户端

原生zookeeper不足

  • 连接对象异步,需要开发人员自己编写代码阻塞等待
  • 连接没有自动重连机制
  • watcher注册后只生效一次
  • 不支持递归创建树形节点

curator特点

  • 解决session超时重连问题
  • watcher反复注册
  • 简化api
  • 链式编程风格
  • 提供分布式锁、集群领导选举、共享计数器、缓存机制等工具类

2 代码实现

2.1 建立连接

	private CuratorFramework curatorFramework = null;

	@Before
	public void init() throws Exception {
		//1 重试策略:初试时间为3s 重试10次
		RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 10);
		//2 通过工厂创建连接
		curatorFramework = CuratorFrameworkFactory.builder()
				.connectString(Constant.ZK_HOST)
				.sessionTimeoutMs(Constant.SESSION_TIMEOUT)
				.retryPolicy(retryPolicy)
				.build();
		//3 开启连接
		curatorFramework.start();
    }

2.2 创建节点

	@Test
	public void testCreate() throws Exception {
		curatorFramework.create()
				.withMode(CreateMode.PERSISTENT)
				.forPath(Constant.ROOT_PATH, "root".getBytes());
	}

	@Test
	public void testCreateWithParent() throws Exception {
		curatorFramework.create()
				.creatingParentsIfNeeded()
				.withMode(CreateMode.PERSISTENT)
				.forPath(Constant.ROOT_PATH + "/path1", "path1".getBytes());
	}

	@Test
	public void testCreateAsync() throws Exception {
		curatorFramework.create()
				.withMode(CreateMode.PERSISTENT)
				.inBackground((client, event) -> {
                    String path = event.getPath();
                    String data = new String(event.getData());
                    System.out.println("create data end, path:" + path + ", data:" + data);
                })
				.forPath(Constant.ROOT_PATH, "root".getBytes());
	}

2.3 查看节点

	@Test
	public void testGet() throws Exception {
		String data = new String(curatorFramework.getData().forPath(Constant.ROOT_PATH));
		System.out.println("get data:" + data);
	}

	@Test
	public void testGetWithStat() throws Exception {
		Stat stat = new Stat();
		String data = new String(curatorFramework.getData().storingStatIn(stat).forPath(Constant.ROOT_PATH));
		System.out.println("get data:" + data + ", version:" + stat.getVersion());
	}

    @Test
    public void testGetAsync() throws Exception {
        curatorFramework.getData()
                .inBackground((client, event) -> {
                    String path = event.getPath();
                    String data = new String(event.getData());
                    System.out.println("get data end, path:" + path + ", data:" + data);
                })
                .forPath(Constant.ROOT_PATH);
    }

2.4 修改节点

    @Test
    public void testUpdate() throws Exception {
        curatorFramework.setData().forPath(Constant.ROOT_PATH, "root update".getBytes());
    }

    @Test
    public void testUpdateWithVersion() throws Exception {
        curatorFramework.setData().withVersion(1).forPath(Constant.ROOT_PATH, "root update".getBytes());
    }

    @Test
    public void testUpdateAsync() throws Exception {
        curatorFramework.setData()
                .inBackground((client, event) -> {
                    String path = event.getPath();
                    String data = new String(event.getData());
                    System.out.println("update data end, path:" + path + ", data:" + data);
                })
                .forPath(Constant.ROOT_PATH, "root update".getBytes());
    }

2.5 删除节点

    @Test
    public void testDelete() throws Exception {
        curatorFramework.delete().forPath(Constant.ROOT_PATH);
    }

    @Test
    public void testDeleteWithVersion() throws Exception {
        curatorFramework.delete().withVersion(1).forPath(Constant.ROOT_PATH);
    }

    @Test
    public void testDeleteAsync() throws Exception {
        curatorFramework.delete()
                .inBackground((client, event) -> {
                    String path = event.getPath();
                    String data = new String(event.getData());
                    System.out.println("delete data end, path:" + path + ", data:" + data);
                })
                .forPath(Constant.ROOT_PATH);
    }

    @Test
    public void deleteWithChildren() throws Exception {
        curatorFramework.delete().deletingChildrenIfNeeded().forPath(Constant.ROOT_PATH);
    }

2.6 查看子节点

    @Test
    public void testGetChildren() throws Exception {
        List<String> list = curatorFramework.getChildren().forPath(Constant.ROOT_PATH);
        System.out.println(list);
    }

    @Test
    public void testGetChildrenAsync() throws Exception {
        curatorFramework.getChildren()
                .inBackground((client, event) -> {
                    String path = event.getPath();
                    String data = new String(event.getData());
                    System.out.println("get data children end, path:" + path + ", data:" + data + " children:" + event.getChildren());
                })
                .forPath(Constant.ROOT_PATH);
    }

2.7 查看节点是否存在

    @Test
    public void testExists() throws Exception {
        Stat stat = curatorFramework.checkExists().forPath(Constant.ROOT_PATH);
    }

    @Test
    public void testExistsAsync() throws Exception {
        Stat stat = curatorFramework.checkExists()
                .inBackground((client, event) -> {
                    System.out.println("check exists end, stat:" + event.getStat());
                })
                .forPath(Constant.ROOT_PATH);
    }

2.8 watcher监听

    @Test
    public void testWatch() throws Exception {
        final NodeCache cache = new NodeCache(curatorFramework, Constant.ROOT_PATH, false);
        cache.start(true);
        cache.getListenable().addListener(() -> {
            ChildData childData = cache.getCurrentData();
            if (Objects.isNull(childData)) {
                log.info("data removed");
            } else {
                log.info("data changed, path:{}, data:{}, status:{}", childData.getPath(), childData.getData(), childData.getStat());
            }
        });
    }

    @Test
    public void testWatchChildren() throws Exception {
        // 建立一个PathChildrenCache缓存,第三个参数为是否接受节点数据内容 如果为false则不接受
        PathChildrenCache pathChildrenCache = new PathChildrenCache(curatorFramework, Constant.ROOT_PATH, true);
        pathChildrenCache.start(PathChildrenCache.StartMode.POST_INITIALIZED_EVENT);
        pathChildrenCache.getListenable().addListener((cf, event) -> {
            ChildData data = event.getData();
            switch (event.getType()) {
                case CHILD_ADDED:
                    log.info("child added, path:{}, data:{}" + data.getPath(), data.getData());
                    break;
                case CHILD_UPDATED:
                    log.info("child updated, path:{}, data:{}" + data.getPath(), data.getData());
                    break;
                case CHILD_REMOVED:
                    log.info("child removed, path:{}, data:{}" + data.getPath(), data.getData());
                    break;
                default:
                    break;
            }
        });
    }

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值