常用的ZK有三种:
1、使用 Zookeeper原生API
2、使用 ZkClient
3、使用 Curator
Curator是Netflix公司开源的一个Zookeeper客户端,与Zookeeper提供的原生客户端相比,Curator的抽象层次更高,简化了Zookeeper客户端的开发量。
-
封装ZooKeeper client与ZooKeeper server之间的连接处理;
-
提供了一套Fluent风格的操作API;
-
提供ZooKeeper各种应用场景(recipe,比如共享锁服务,集群领导选举机制)的抽象封装。
Curator几个组成部分
-
Client:是ZooKeeper客户端的一个替代品,提供了一些底层处理和相关的工具方法。
-
Framework:用来简化ZooKeeper高级功能的使用,并增加了一些新的功能,比如管理到ZooKeeper集群的连接,重试处理。
-
Recipes:实现了通用ZooKeeper的recipe,该组件建立在Framework的基础之上
-
Utilities:各种ZooKeeper的工具类。
-
Errors:异常处理,连接,恢复等。
-
Extensions:recipe扩展
RetryPolicy 连接策略
-
RetryOneTime:只重连一次.
-
RetryNTime:指定重连的次数N.
-
RetryUtilElapsed:指定最大重连超时时间和重连时间间隔,间歇性重连直到超时或者链接成功。
-
ExponentialBackoffRetry:基于"backoff(退避)"方式重连,和RetryUtilElapsed的区别是重连的时间间隔是动态的。
-
BoundedExponentialBackoffRetry:同ExponentialBackoffRetry,增加了最大重试次数的控制。
创建会话
CuratorFrameworkFactory.newClient(String connectString, int sessionTimeoutMs, int connectionTimeoutMs, RetryPolicy retryPolicy) CuratorFrameworkFactory.builder().connectString("192.168.11.56:2180") .sessionTimeoutMs(30000).connectionTimeoutMs(30000) .canBeReadOnly(false) .retryPolicy(new ExponentialBackoffRetry(1000, Integer.MAX_VALUE)) .build();
创建节点
client.create().creatingParentIfNeeded()
.withMode(CreateMode.PERSISTENT)
.withACL(aclList)
.forPath(path, "hello, zk".getBytes());
删除节点
client.delete().guaranteed().deletingChildrenIfNeeded().withVersion(version).forPath(path)
获取节点
client.getData().storingStatIn(stat).forPath(path);
client.getChildren().forPath(path);
更新节点
client.setData().withVersion(version).forPath(path, data)
判断节点是否存在
client.checkExists().forPath(path);
设置权限
Build.authorization(String scheme, byte[] auth) client.setACL().withVersion(version) .withACL(ZooDefs.Ids.CREATOR_ALL_ACL) .forPath(path);
监听器
Cache是curator中对事件监听的包装,对事件的监听可以近似看做是本地缓存视图和远程ZK视图的对比过程
-
NodeCache 节点缓存用于处理节点本身的变化,回调接口NodeCacheListener
-
PathChildrenCache 子节点缓存用于处理节点的子节点变化,回调接口PathChildrenCacheListener
-
TreeCache/NodeCache和PathChildrenCache的结合体,回调接口TreeCacheListener
NodeCache nc = new NodeCache(client, path, false); nc.start(); nc.getListenable().addListener(new NodeCacheListener() { @Override public void nodeChanged() throws Exception { ... } });