zookeeper的客户端Curator的API

一、前言

    Curator框架提供了一套高级的API, 简化了ZooKeeper的操作,这里来介绍一下API;

二、Curator常用的API

2.1 连接zookeeper

    private CuratorFramework client;

    @Before
    public void init() {
        /**
         * 构造方法
         * public static CuratorFramework newClient(String connectString, int sessionTimeoutMs, int connectionTimeoutMs, RetryPolicy retryPolicy)
         * @param connectString: zookeeper服务列表,ip端口号逗号分隔,格式为   host1:port1,host2:port2,host3:port3
         * @param sessionTimeoutMs: 会话超时时间,单位毫秒,默认60000ms
         * @param connectionTimeoutMs: 连接创建超时时间,单位毫秒,默认60000ms
         * @param retryPolicy: 重试策略,内置四种,可实现自定义重试策略
         */
        this.client = CuratorFrameworkFactory.newClient("120.78.215.216:2181", 3000, 3000, new ExponentialBackoffRetry(3000, 3));
        this.client.start();
    }

2.2 创建节点

    @Test
    public void addNode() throws Exception{
        //创建一个节点
        client.create().forPath("/create1");
        //创建一个带有初始值的节点,,值类型应为byte[]
        client.create().forPath("/create2", "create2".getBytes());
        /**
         * 创建持久化顺序节点
         * CreateMode.
         *     PERSISTENT(0, false, false), 持久化节点
         *     PERSISTENT_SEQUENTIAL(2, false, true), 持久化顺序节点
         *     EPHEMERAL(1, true, false), 临时节点
         *     EPHEMERAL_SEQUENTIAL(3, true, true); 临时顺序节点
         */
        client.create().withMode(CreateMode.PERSISTENT_SEQUENTIAL).forPath("/create3");
        client.create().withMode(CreateMode.PERSISTENT_SEQUENTIAL).forPath("/create3");
        //在后台执行操作
        client.create().inBackground().forPath("/create4");
        //递归创建节点,若创建节点的父节点不存在是会报错的
        client.create().creatingParentsIfNeeded().forPath("/create5/create6/create7");
        client.create().compressed().forPath("/create8");
        /**
         * 避免在成功创建节点后,在返回客户端结果前服务端崩溃,导致客户端无法的得到当前创建节点的路径响应
         * 若创建失败,withProtection() 会进行重试,
         * 官方解释 -> ctrl + left mouse button
         * @see : http://curator.apache.org/apidocs/org/apache/curator/framework/api/CreateBuilderMain.html#withProtection--
         */
        String path = client.create().withProtection().forPath("/create9", "create9".getBytes());

    }

运行后的输出:

1ab52835d9d02fd44aa8d4221be1e07b9e1.jpg  从左图可以得到如下结论:

1.创建不带初始值的节点时,默认值为ip,

2.创建顺序节点会自动给节点名字后面加序号

 

 

2.3 获取节点

    @Test
    public void getData() throws Exception{
        //forPath()返回值为byte[],因此需要new String(byte[] byte)方法转换
        client.getData().forPath("/create1");
        log.info(String.format("create2 -> %s", new String(client.getData().forPath("/create2"))));
    }

2.4 更新节点数据

    @Test
    public void setData() throws Exception{
 
        //默认值更新节点数据
        client.setData().forPath("/setData1");
        //给定值更新节点数据
        client.setData().forPath("/setData2","setData2".getBytes());
        //CAS操作,更新指定数据版本节点数据,更新成功后数据版本+1,若版本不匹配,则更新失败
        client.setData().withVersion(21).forPath("/setData2", "setData2".getBytes());
    }

2.5 删除节点数据

    @Test
    public void del() throws Exception{
        //删除节点
        client.delete().forPath("/create1");
        /**
         * 递归删除create6节点,create5节点不会被删除,
         * 是不可以forPath("/create6")的,需要指明全路径,
         * 因为有可能存在/create6节点,与/create5/create6是不同的描述
         */
        client.delete().deletingChildrenIfNeeded().forPath("/create5/create6");
        //删除指定版本的节点数据
        client.delete().withVersion(-1).forPath("/create5");
        //guaranteed()类似于创建节点时的withProtection()方法一样,在有效会话内重试删除,直至删除成功
        client.delete().guaranteed().forPath("/create7");
    }

注: 在更新和删除节点数据的时候都支持CAS及乐观锁(版本号),版本号是从0开始的,默认-1理论上只是用来占位的而已,因此对于指定-1则不会生效;

    在对节点数据进行更新是,无论是否指定数据版本,成功更新后版本号都会+1;

2.6 获取子节点


    @Test
    public void child() throws Exception{
        client.create().creatingParentsIfNeeded().forPath("/parent/child1");
        client.create().creatingParentsIfNeeded().forPath("/parent/child2");
        client.create().creatingParentsIfNeeded().forPath("/parent/child3");
        client.create().creatingParentsIfNeeded().forPath("/parent/child4/son1");
        //获取指定节点的子节点
        List<String> childrens = client.getChildren().forPath("/parent");
        log.info(String.format("parent's child node are -> %s", childrens));
    }

    输出:

parent's child node are -> [child4, child2, child3, child1]

    可见,该方法只能获取一级子节点;

2.7 判断节点是否存在

    @Test
    public void exist() throws Exception{
        Stat stat = client.checkExists().forPath("/parent");
        log.info("stat ->" + stat.toString());
        Stat stat1 = client.checkExists().forPath("/parentNotExist");
        log.info("stat1 ->" + stat1.toString());
    }

    输出:

stat ->10781,10781,1556645668186,1556645668186,0,4,0,0,0,4,10786
java.lang.NullPointerException
	at com.river.service.CuratorNodeOperator.exist(CuratorNodeOperator.java:112)

    可知若节点不存在,则stat对象为null;

2.8 事务内操作

    @Test
    public void transaction() throws Exception{
        //事务内
        //检查节点是否存在
        client.inTransaction().check().forPath("/parent")
                .and()
                //创建节点
                .create().forPath("/check")
                .and()
                //设置节点数据
                .setData().forPath("/check","check".getBytes())
                .and()
                //提交事务
                .commit();
    }

 

 

 

未完待续...先睡觉了

转载于:https://my.oschina.net/JackieRiver/blog/3044638

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值