Zookeeper客户端对比选择

本文思维导图

使用框架的好处是自带一套实用的API,但是Zookeeper虽然非常强大,但是社区却安静的可怕,版本更新较慢,下面会先从zookeeper原生API的不足说起,然后引出现在流行的开源客户端工具。

1.原生API

  • 1.创建连接的时候是异步的,所以我们在开发的时候需要人工的写代码等待创建节点的状态,如果需要的话。
  • 2.连接时无超时重连机制。本人觉得这个非常重要,因为在现实使用中,网络是不可信的,在创建节点的时候要考虑到网络的不稳定性。因此,超时重连机制是非常必要的。
  • 3.zookeepr的通信是网络通信,因此在数据通信的时候会消耗一定的网络IO和带宽。但zookeeper没有序列化机制,需要开发者自行开发。
  • 4.Watcher注册一次,触发后会自动失效。
  • 5.不支持递归创建树形节点。这点是比较有用的,类似Linux的命令:mkdir -p /xxx/xxx/

基于以上的一些不足,引起了业界一些大佬的不满,因此它们自行开发了一些开源的客户端工具。比如ZkClient和Curator。对前者简单介绍,现在使用最多的是后者。

2.ZkClient

2.1 ZkClient概述

ZkClient是Github上一个开源的zk客户端,由datameer的工程师Stefan Groschupf和Peter Voss一起开发(最仰慕的就是这类大佬,类似Linus那样,一不爽写个开源版本(git)出来...)

  • 解决session会话超时重连。
  • Watcher反复注册。
  • 简化开发api。

当然还有很多的很多修改的功能,使用也很简单,但是社区不活跃,连api文档都不完善,对于我们来说只能看源码来开发应用了,也略有麻烦的。有兴趣的开源上github看看。 https://github.com/sgroschupf/zkclient

2.2 ZkClien API

  • 创建客户端 ZkClient zkclient = new ZkClient("192.168.17.128:2181,192.168.17.129:2181,192.168.17.130:2181",5000);
  • 创建节点 zkclient.create(path, data, CreateMode.PERSISTENT);
  • 删除节点 zkclient.delete(path);
  • 获取子节点 zkclient.getChildren(path);
  • 关闭客户端 zkclient.close();
  • 读节点数据 zkclient.readData(path);
  • 判断节点是否存在 zkclient.exists(path);

3.Curator

3.1 Curator概述

Curator是Apache基金会的顶级项目之一。Apache基金会就类似万能储备室,把全球顶级的开源项目收纳其中,造福一方百姓啊。

  • 下面是Curator对比原生zk的API和ZkClient比较重要的完善点:
  • 解决session会话超时重连。
  • Watcher反复注册。
  • 简化开发api。
  • 遵循Fluent风格Api规范。
  • NodeExistsException异常处理。
  • ......

3.2 Curator API介绍

  • 创建会话

  • 1.使用CuratorFrameworkFactory工厂的两个静态方法创建客户端

  • 2.Start()方法启动

    RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);

    client = CuratorFrameworkFactory.builder()

    .connectString("localhost:2181,localhost:2182")

    .sessionTimeoutMs(10000).retryPolicy(retryPolicy)

    .namespace("base").build();

    client.start();

  • 1.重试策略(实现接口RetryPolicy可以自定义重试策略)

    boolean allowRetry(int retryCount, long elapsedTimeMs, RetrySleeper sleeper)

  • 2.默认四种重试策略: Exponential BackoffRetry、RetryNTimes、RetryOneTime、

    RetryUntilElapsed

  • 2.1 ExponentialBackoffRetry

  • ExponentialBackoffRetry(int baseSleepTimeMs, int maxRetries)

  • ExponentialBackoffRetry(int baseSleepTimeMs, int maxRetries, int maxSleepMs)

  • 当前应该sleep的时间: baseSleepTimeMs * Math.max(1, random.nextInt(1 << (retryCount + 1)))

  • 2.2 RetryNTimes

  • RetryNTimes(int n, int sleepMsBetweenRetries)

  • 2.3 RetryOneTime

  • RetryOneTime(int sleepMsBetweenRetry)

  • 2.4 RetryUntilElapsed

    RetryUntilElapsed(int maxElapsedTimeMs, int sleepMsBetweenRetries)

  • 3.Fluent风格的API

  • 定义:一种面向对象的开发方式,目的是提高代码的可读性

  • 实现方式͹通过方法的级联或者方法链的方式实现

  • 例子:

      client = CuratorFrameworkFactory.builder()
    .connectString("localhost:2181,localhost:2182")
    .sessionTimeoutMs(10000).retryPolicy(retryPolicy)
    .namespace("base").build();
  • 4.常用API

  • 4.1创建节点

      public void createNode(String path, byte[] data) throws Exception {
    client.getZookeeperClient().getZooKeeper().addAuthInfo("digest", "test:123456".getBytes());
    client.create().creatingParentsIfNeeded()
    .withMode(CreateMode.PERSISTENT).withACL(Ids.CREATOR_ALL_ACL)
    .forPath(path, data);
    }
  • 4.2删除节点

      public void deleteNode(String path, int version) throws Exception {
    client.delete().guaranteed().deletingChildrenIfNeeded().withVersion(version)
    .inBackground(new DeleteCallBack()).forPath(path);
    }
  • 4.3读取节点

      public void readNode(String path) throws Exception {
    byte[] data = client.getData().inBackground(new DeleteCallBack()).forPath(path);
    System.out.println(path + "的数据:" + new String(data));
    }
  • 4.4更新节点数据

      public void updateNode(String path, byte[] data, int version)
    throws Exception {
    client.setData().withVersion(version).inBackground(new DeleteCallBack()).forPath(path, data);
    }
  • 4.5获取子节点

      public void getChildren(String path) throws Exception {
    List<String> children = client.getChildren().usingWatcher(new WatcherTest()).forPath("/test");
    for (String pth : children) {
    System.out.println("child=" + pth);
    }
    }

4.6为节点添加监听

  • NodeCache

  • 监听数据节点的内容变更

  • 监听节点的创建,即如果指定的节点不存在,则节点创建后,会触发这个监听

  • PathChildrenCache

  • 监听指定节点的子节点变化情况

  • 包括新增子节点,子节点数据变更和子节点删除

     public void addNodeDataWatcher(String path) throws Exception {
    final NodeCache nodeC = new NodeCache(client, path);
    nodeC.start(true);
    nodeC.getListenable().addListener(new NodeCacheListener() {
    public void nodeChanged() throws Exception {
    String data = new String(nodeC.getCurrentData().getData());
    System.out.println("path=" + nodeC.getCurrentData().getPath()
    + ":data=" + data);
    }
    });
    }

4.7异步回调

  • inBackground()
  • inBackground(Object context)
  • inBackground(BackgroundCallback callback)
  • inBackground(BackgroundCallback callback, Object context)
  • inBackground(BackgroundCallback callback, Executor executor)
  • inBackground(BackgroundCallback callback, Object context, Executor executor)

Curator的回调与zk的原生异步api相同,多了一个线程池,用于执行回调。

异步操作事件状态:event.getType()

异步操作事件状态码:event.getResultCode()

以上就是Curator常用的API,都是利用这些API来进行更加复杂的应用开发的,比如分布式锁,集群管理等应用。

4.小结

好的开源工具解放我们的开发,但是不要在其中迷失,还要深入的了解其中的设计原理,不能只是调用API,要学习人家的思想,这样才能跟随大神的脚步,提升自己的实力。

Zookeeper客户端对比选择_4的更多相关文章

  1. 服务注册发现与注册中心对比-Eureka,Consul,Zookeeper,Nacos对比

    服务注册发现与注册中心对比-Eureka,Consul,Zookeeper,Nacos对比 注册中心简介 流程和原理 基础流程 核心功能 1.Eureka.Consul.Zookeeper三者异同点 ...

  2. 【分布式】Zookeeper客户端

    一.前言 前篇博客分析了Zookeeper的序列化和通信协议,接着继续学习客户端,客户端是开发人员使用Zookeeper最主要的途径,很有必要弄懂客户端是如何与服务端通信的. 二.客户端 2.1 客户 ...

  3. zookeeper 客户端编程

    zookeeper是一个分布式的开源的分布式协调服务,用它可以来现同步服务,配置维护.zookeeper的稳定性也是可以保证的,笔者曾参与过的使用zookeeper的两个应用,一个是用zookeepe ...

  4. Zookeeper客户端Curator的使用,简单高效

    Curator是Netflix公司开源的一个Zookeeper客户端,与Zookeeper提供的原生客户端相比,Curator的抽象层次更高,简化了Zookeeper客户端的开发量. 1.引入依赖: ...

  5. Zookeeper客户端Curator使用详解

    Zookeeper客户端Curator使用详解 前提 最近刚好用到了zookeeper,做了一个基于SpringBoot.Curator.Bootstrap写了一个可视化的Web应用: zookeep ...

  6. zookeeper如何实现负载均衡的?(具体连接哪一个zookeeper服务器的选择?)阿里面试

    如果想了解web 6大负载均衡算法,参考:六大Web负载均衡原理与实现 主要是三点:负载均衡算法,健康检查和会话保持 1:首先,我们要了解,我们的应用程序,比如java web程序,里面配置了10个z ...

  7. zookeeper(六):Zookeeper客户端Curator的API使用详解

    简介 Curator是Netflix公司开源的一套zookeeper客户端框架,解决了很多Zookeeper客户端非常底层的细节开发工作,包括连接重连.反复注册Watcher和NodeExistsEx ...

  8. 转:Zookeeper客户端Curator使用详解

    原文:https://www.jianshu.com/p/70151fc0ef5d Zookeeper客户端Curator使用详解 前提 最近刚好用到了zookeeper,做了一个基于SpringBo ...

  9. zookeeper系列(八)zookeeper客户端的底层详解

    作者:leesf    掌控之中,才会成功:掌控之外,注定失败.出处:http://www.cnblogs.com/leesf456/p/6098255.html 尊重原创,共同学习进步:  一.前言 ...

随机推荐

  1. <正则吃饺子> :关于redis集群的搭建、集群测试、搭建中遇到的问题总结

    项目中使用了redis ,对于其基本的使用,相对简单些,根据项目中已经提供的工具就可以实现基本的功能,但是只是这样的话,对于redis还是太肤浅,甚至刚开始时候,集群.多节点.主从是什么,他们之间是什 ...

  2. C++风格与C风格文件读写效率测试-vs2015,vs2017

    void test_write() { ; const char* c_plus_write_file = "H://c_plus_write_file.txt"; const c ...

  3. 【原】Coursera—Andrew Ng机器学习—课程笔记 Lecture 8_Neural Networks Representation 神经网络的表述

    神经网络是一种受大脑工作原理启发的模式. 它在许多应用中广泛使用:当您的手机解释并理解您的语音命令时,很可能是神经网络正在帮助理解您的语音; 当您兑现支票时,自动读取数字的机器也使用神经网络. 8.1 ...

  4. 【Android】Android 4.0 无法接收开机广播的问题

    [Android]Android 4.0 无法接收开机广播的问题   前面的文章 Android 开机广播的使用 中 已经提到Android的开机启动,但是在Android 4.0 有时可以接收到开机 ...

  5. Postman之token动态获取

    目前项目涉及PC及APP端接口共用问题,后台接口给登陆后的用户设置了一个token,接口调用时请求头的参数值必须要动态生成,为了解决这个问题,查看Postman API文档,配置了可以方便后端开发者的 ...

  6. codeforce452DIV2——F. Letters Removing

    题意:给一个字符串和m个操作,每次给出l,r,c,把字符串中l-r这段区间的字符为c的字符删掉,求最后的字符串.(n,m<=2e5)线段树.注意这个区间修改和普通区间修改的区别. 他们都是用树状 ...

  7. 【总结整理】如何判断伪需求(摘自pmcafe)

    1.客户不会直接提需求,都是给解决方案,所以得到用户的反馈之后,先反推一下是很必要的,为什么客户会有这样的方案 总结:方案不合适 例如:客户只会说我要快马,反推一下,其实客户是想要更快,这样的话,解决 ...

  8. mysql GROUP_CONCAT 可以将分组的字段进行拼接处理.

    GROUP_CONCAT 可以将分组的字段进行拼接处理. SELECT g.id, g.merchant_id, g. NAME, g.introduction, g.cover_pic, g.pla ...

  9. 目录、目录项、文件名、inode、软硬链接的关系

    对于Unix系列的操作系统,大多都有v节点.但是对于linux来说,只有通用的i节点,却没有v节点. 下面来探讨一下,linux下的i节点. linux中,文件查找不是通过文件名称来查找的.实际上是通 ...

  10. CentOS 安装mongodb3.0 二进制包

    1.下载mongodb因为64位系统CentOS,所以下载64位的安装包: wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.0 ...