乐趣区

关于zookeeper:zookeeper分布式锁

客户端抉择

zookeeper 的 Java 客户端次要有 zkclient 和 Curator,此篇文章介绍 Curator,就冲他官网的简介,zookeeper 书的作者 Patrick Hunt 给了这么高的评估:Guava is to Java what Curator is to Zookeeper。

实际操作下来,Curator 的确比 zkclient 更全面,代码编写也更加优雅。

引入 jar 包

Curator 次要提供了三个包

  • curator-framework:对 zookeeper 操作的封装
  • curator-client:提供了一些客户端的操作
  • curator-recipes:封装了一些高级个性

咱们能够间接援用 curator-recipes,它外面蕴含了其余两个 jar 包,然而要留神 zookeeper 的版本,官网中给出了上面提醒:

基本操作

客户端实例的创立

第一种

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

retry 是重试策略,间隔时间是 2 的指数增长,比方第一次期待 1s,第二次 2s,第三次 4s。。。

第一个参数是距离根底单位,原始是毫秒;第二个参数是重试次数。

CuratorFrameworkFactory.newClient 创立客户端,传入 zookeeper 的连贯地址和重试策略。

第二种

ExponentialBackoffRetry retry = new ExponentialBackoffRetry(1000, 3);
CuratorFramework client = CuratorFrameworkFactory.builder()
        .connectString("123.206.212.170:2181")
        .connectionTimeoutMs(10000)
        .sessionTimeoutMs(10000)
        .retryPolicy(retry).build();

重试策略和下面一样,客户端通过 CuratorFrameworkFactory.builder() 创立,connectionTimeoutMs 示意连贯超时工夫,sessionTimeoutMs 示意会话超时工夫。

创立节点

CuratorFramework client = client();
client.start();

String path = "/demo/curd/node-2";
client.create()
        .creatingParentsIfNeeded()
        .withMode(CreateMode.PERSISTENT)
        .forPath(path, "world".getBytes("utf-8"));
client.close();

curator 的操作方法,根本都是链式调用,比起 zkclient 要优雅很多;

creatingParentsIfNeeded() 示意如果父节点没有,就一起创立;

withMode(CreateMode.PERSISTENT) 是创立的节点类型,zookeeper 的节点有四种类型:

  • PERSISTENT:长久化节点
  • PERSISTENT_SEQUENTIAL:长久化程序节点
  • EPHEMERAL:长期节点
  • EPHEMERAL_SEQUENTIAL:长期程序节点

最初.forPath 设置创立的节点门路和节点携带的内容。 创立后果能够通过 IDEA 的 zookeeper 插件可视化查看,插件装置办法自行百度。

删除节点

CuratorFramework client = client();
client.start();

String path = "/demo/curd/node-2";
client.delete().forPath(path);
client.close();

删除节点调用 delete 办法即可。

批改节点

CuratorFramework client = client();
client.start();

String path = "/demo/curd/node-1";
client.setData().forPath(path, "hello world".getBytes("utf-8"));
client.close();

批改节点调用 setData() 办法,前面 forPath 办法传入批改后的内容。

查问节点

CuratorFramework client = client();
client.start();

String path = "/demo/curd/node-1";
byte[] bytes = client.getData().forPath(path);
System.out.println(new String(bytes));

List<String> list = client.getChildren().forPath("/demo");
list.forEach(System.out::println);
client.close();

查问以后节点内容应用 getData() 办法,也能够用过 getChildren() 获取上面的所有子节点,返回各个节点门路汇合。

异步创立节点

CuratorFramework client = client();
client.start();

String path = "/demo/curd/node-4";
client.create()
        .creatingParentsIfNeeded()
        .withMode(CreateMode.PERSISTENT)
        .inBackground((c,e) ->{System.out.println("================");
            System.out.println(e);
        }).forPath(path);
Thread.sleep(10000);

节点创立和批改能够异步操作,只有调用 inBackground 办法,当节点创立胜利当前,会走此办法外面的回调函数。

节点监听

CuratorFramework client = client();
client.start();
CountDownLatch countDownLatch = new CountDownLatch(1);
Watcher w = new Watcher() {
    @Override
    public void process(WatchedEvent watchedEvent) {System.out.println("监听到的变动 watchedEvent =" + watchedEvent);
        countDownLatch.countDown();}
};
client.getData().usingWatcher(w).forPath("/demo/curd/node-1");
countDownLatch.await();
client.close();

实例化 Watcher,并实现 process 办法,当节点发生变化,会执行 process 办法,应用 usingWatcher 办法增加监听办法。


<center> 扫一扫,关注我 </center>

退出移动版