Apache Curator简单介绍

原文链接:https://www.dubby.cn/detail.html?id=9099

提供了一个抽象级别更高的API,来操作Zookeeper,类似Guava提供的很多工具,让Java书写起来更加方便。至于有没有用,那就要看每个人自己的理解了。

1、依赖

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

更多版本和依赖

2、连接Zookeeper

RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", retryPolicy);
client.start();

3、增删改查

/**
 * Zookeeper的CRUD操作
 */
public class CrudExamples {

    /**
     * 给指定的ZNode设置值,不能嵌套创建目录
     * 如果节点已经存在,会抛异常org.apache.zookeeper.KeeperException$NodeExistsException: KeeperErrorCode = NodeExists for /path
     */
    public static void create(CuratorFramework client, String path, byte[] payload) throws Exception {
        client.create().forPath(path, payload);
    }

    /**
     * 创建临时节点
     * 需要注意:虽说临时节点是session失效后立刻删除,但是并不是client一断开连接,session就立刻会失效
     * 失效是由zk服务端控制的,每次连接时,客户端和服务端会协商一个合理的超时时间
     * 如果超过了超时时间client都一直美哦与发送心跳,才回真的删除这个session创建的临时节点
     */
    public static void createEphemeral(CuratorFramework client, String path, byte[] payload) throws Exception {
        client.create().withMode(CreateMode.EPHEMERAL).forPath(path, payload);
    }


    public static String createEphemeralSequential(CuratorFramework client, String path, byte[] payload) throws Exception {
        return client.create().withProtection().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath(path, payload);
    }

    public static void setData(CuratorFramework client, String path, byte[] payload) throws Exception {
        client.setData().forPath(path, payload);
    }

    public static void setDataAsync(CuratorFramework client, String path, byte[] payload) throws Exception {
        CuratorListener listener = new CuratorListener() {
            @Override
            public void eventReceived(CuratorFramework client, CuratorEvent event) throws Exception {
                if (event != null)
                    System.out.println(event.toString());
            }
        };
        client.getCuratorListenable().addListener(listener);

        client.setData().inBackground().forPath(path, payload);
    }

    public static void setDataAsyncWithCallback(CuratorFramework client, BackgroundCallback callback, String path, byte[] payload) throws Exception {
        client.setData().inBackground(callback).forPath(path, payload);
    }

    public static void delete(CuratorFramework client, String path) throws Exception {
        client.delete().forPath(path);
    }

    public static void guaranteedDelete(CuratorFramework client, String path) throws Exception {
        client.delete().guaranteed().forPath(path);
    }

    public static List<String> watchedGetChildren(CuratorFramework client, String path) throws Exception {
        return client.getChildren().watched().forPath(path);
    }

    public static List<String> watchedGetChildren(CuratorFramework client, String path, Watcher watcher) throws Exception {
        return client.getChildren().usingWatcher(watcher).forPath(path);
    }
}

使用上面的增删改查来测试:

public class CuratorStartupDemo {

    private static CuratorFramework CLIENT;
    private static final String CHARSET = "UTF-8";

    static {
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
        CLIENT = CuratorFrameworkFactory.newClient("127.0.0.1:2181", retryPolicy);
    }


    public static void main(String[] args) throws Exception {
        CLIENT.start();
        System.out.println(CLIENT.getZookeeperClient().getConnectionTimeoutMs());

        CrudExamples.create(CLIENT, "/x", "test".getBytes(CHARSET));

        CrudExamples.createEphemeral(CLIENT, "/e", "test".getBytes(CHARSET));

        CrudExamples.setData(CLIENT, "/x", UUID.randomUUID().toString().getBytes(CHARSET));
        CrudExamples.setDataAsync(CLIENT, "/x", UUID.randomUUID().toString().getBytes(CHARSET));
        CrudExamples.setDataAsyncWithCallback(CLIENT, ((client, event) -> {
            System.out.println(event.getPath());
        }), "/x", UUID.randomUUID().toString().getBytes(CHARSET));

        CrudExamples.createEphemeralSequential(CLIENT, "/x", "test".getBytes(CHARSET));
        CrudExamples.createEphemeralSequential(CLIENT, "/x", "test".getBytes(CHARSET));
        CrudExamples.createEphemeralSequential(CLIENT, "/x", "test".getBytes(CHARSET));
        CrudExamples.createEphemeralSequential(CLIENT, "/x", "test".getBytes(CHARSET));

        CuratorListener listener = new CuratorListener() {
            @Override
            public void eventReceived(CuratorFramework client, CuratorEvent event) throws Exception {
                if (event != null)
                    System.out.println(event.toString());

                //watcher是一次性的,每次watch后需要重新设置watcher
                if ("/x".equals(event.getPath())) {
                    CrudExamples.watchedGetChildren(CLIENT, "/x");
                }
            }
        };
        CLIENT.getCuratorListenable().addListener(listener);
        CrudExamples.watchedGetChildren(CLIENT, "/x");
        CrudExamples.create(CLIENT, "/x/a", null);
        CrudExamples.create(CLIENT, "/x/b", null);
        CrudExamples.delete(CLIENT, "/x/a");
        CrudExamples.delete(CLIENT, "/x/b");


        MyWatcher myWatcher = new MyWatcher("/x", CLIENT);
        CrudExamples.watchedGetChildren(myWatcher.curatorFramework, myWatcher.getPath(), myWatcher);

        System.out.println("task completed");
        new CountDownLatch(1).await();
    }

    static class MyWatcher implements Watcher {

        private String path;
        private CuratorFramework curatorFramework;

        public MyWatcher(String path, CuratorFramework curatorFramework) {
            this.path = path;
            this.curatorFramework = curatorFramework;
        }

        @Override
        public void process(WatchedEvent event) {
            System.out.println(event.toString());
            try {
                //watcher是一次性的,每次watch后需要重新设置watcher
                CrudExamples.watchedGetChildren(this.curatorFramework, this.getPath(), this);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        public String getPath() {
            return path;
        }

        public CuratorFramework getCuratorFramework() {
            return curatorFramework;
        }
    }

}

转载于:https://my.oschina.net/dubby/blog/2248682

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值