三种常用的zk的java api
一、原生api
public class ApiOperatorDemo implements Watcher{
//连接zk的地址
private final static String CONNECTSTRING="192.168.30.10:2181";
// 为了阻塞直到连接成功再继续执行查询
private static CountDownLatch countDownLatch=new CountDownLatch(1);
private static ZooKeeper zookeeper;
// 创建查询结果存储bean,用于存储查询到的节点信息
private static Stat stat=new Stat();
public static void main(String[] args) throws Exception {
// 5000为连接超过5秒就取消,new ApiOperatorDemo() 实现了watch接口,为回调函数;
zookeeper = new ZooKeeper(CONNECTSTRING, 5000, new ApiOperatorDemo());
countDownLatch.await();
// //创建节点,ZooDefs.Ids.OPEN_ACL_UNSAFE为anyone的权限,CreateMode.PERSISTENT为持久节点
String result = zookeeper.create("/node1", "123".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zookeeper.getData("/node1", new ApiOperatorDemo(), stat); //增加一个
System.out.println("创建成功:" + result);
//修改数据
zookeeper.getData("/node1", new ApiOperatorDemo(), stat);
zookeeper.setData("/node1", "deer2".getBytes(), -1);
Thread.sleep(2000);
//删除节点
zookeeper.getData("/node1", new ApiOperatorDemo(), stat);
zookeeper.delete("/node1", -1);
Thread.sleep(2000);
// 创建节点和子节点
String path = "/node11";
//
zookeeper.create(path, "123".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
TimeUnit.SECONDS.sleep(1);
//
Stat stat = zookeeper.exists(path + "/node1", true);
if (stat == null) {//表示节点不存在
zookeeper.create(path + "/node1", "123".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
TimeUnit.SECONDS.sleep(1);
// }
// //修改子路径
zookeeper.setData(path + "/node1", "deer".getBytes(), -1);
TimeUnit.SECONDS.sleep(1);
//获取指定节点下的子节点
List<String> childrens = zookeeper.getChildren("/node11", true);
System.out.println(childrens);
}
}
public void process(WatchedEvent watchedEvent) {
//如果当前的连接状态是连接成功的,那么通过计数器去控制
if(watchedEvent.getState()==Event.KeeperState.SyncConnected){
if(Event.EventType.None==watchedEvent.getType()&&null==watchedEvent.getPath()){
countDownLatch.countDown();
System.out.println(watchedEvent.getState()+"-->"+watchedEvent.getType());
}else if(watchedEvent.getType()== Event.EventType.NodeDataChanged){
try {
System.out.println("数据变更触发路径:"+watchedEvent.getPath()+"->改变后的值:"+
new String(zookeeper.getData(watchedEvent.getPath(),true,stat)));
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else if(watchedEvent.getType()== Event.EventType.NodeChildrenChanged){//子节点的数据变化会触发
try {
System.out.println("子节点数据变更路径:"+watchedEvent.getPath()+"->节点的值:"+
zookeeper.getData(watchedEvent.getPath(),true,stat));
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else if(watchedEvent.getType()== Event.EventType.NodeCreated){//创建子节点的时候会触发
try {
System.out.println("节点创建路径:"+watchedEvent.getPath()+"->节点的值:"+
zookeeper.getData(watchedEvent.getPath(),true,stat));
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else if(watchedEvent.getType()== Event.EventType.NodeDeleted){//子节点删除会触发
System.out.println("节点删除路径:"+watchedEvent.getPath());
}
}
}
}
权限操作:
public class AuthControlDemo implements Watcher{
private final static String CONNECTSTRING="192.168.30.10:2181";
private static CountDownLatch countDownLatch=new CountDownLatch(1);
private static CountDownLatch countDownLatch2=new CountDownLatch(1);
private static ZooKeeper zookeeper;
private static Stat stat=new Stat();
public static void main(String[] args) throws Exception {
zookeeper=new ZooKeeper(CONNECTSTRING, 5000, new AuthControlDemo());
countDownLatch.await();
// acl为权限类型,ZooDefs.Perms.ALL为crwda所有权限,new Id("digest", DigestAuthenticationProvider.generateDigest("root:root"))为digest类型加密密码类型id
ACL acl=new ACL(ZooDefs.Perms.ALL, new Id("digest", DigestAuthenticationProvider.generateDigest("root:root")));
ACL acl2=new ACL(ZooDefs.Perms.CREATE, new Id("ip","192.168.1.1"));
List<ACL> acls=new ArrayList<>();
acls.add(acl);
acls.add(acl2);
// 给当前会话添加可用的 用户权限内容
zookeeper.addAuthInfo("digest","root:root".getBytes());
// 给某个节点指定权限
zookeeper.create("/auth1","123".getBytes(),acls,CreateMode.PERSISTENT);
zookeeper.create("/auth1/auth1-1","123".getBytes(), ZooDefs.Ids.CREATOR_ALL_ACL,CreateMode.EPHEMERAL);
//新建一个会话,此时不能访问以上有权限的节点内容
ZooKeeper zooKeeper1=new ZooKeeper(CONNECTSTRING, 5000, new AuthControlDemo());
countDownLatch.await();
// 给当前会话添加可用的 用户权限内容,此时就可以访问了
zooKeeper1.addAuthInfo("digest","root:root".getBytes());
zooKeeper1.delete("/auth1/auth1-1",-1);
// acl (create /delete /admin /read/write)
//权限模式: ip/Digest(username:password)/world/super
}
public void process(WatchedEvent watchedEvent) {
//如果当前的连接状态是连接成功的,那么通过计数器去控制
if(watchedEvent.getState()==Event.KeeperState.SyncConnected){
if(Event.EventType.None==watchedEvent.getType()&&null==watchedEvent.getPath()){
countDownLatch.countDown();
System.out.println(watchedEvent.getState()+"-->"+watchedEvent.getType());
}
}
}
}
二、zkClient api
pom引入依赖
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
public class ZkClientApiOperatorDemo {
private final static String CONNECTSTRING="192.168.30.10:2181";
public static void main(String[] args) throws InterruptedException {
//新建zkclient
ZkClient zkClient= new ZkClient(CONNECTSTRING,10000);
// zkclient 提供递归创建父节点的功能,在后面加上true表示开启
zkClient.createPersistent("/zkclient/zkclient1/zkclient1-1/zkclient1-1-1",true);
System.out.println("success");
// 删除节点,递归删除
zkClient.deleteRecursive("/zkclient");
// 获取子节点
List<String> list=zkClient.getChildren("/node11");
System.out.println(list);
// watch机制,修改节点值后触发
zkClient.subscribeDataChanges("/node11", new IZkDataListener() {
@Override
public void handleDataChange(String s, Object o) throws Exception {
System.out.println("节点名称:"+s+"->节点修改后的值"+o);
}
@Override
public void handleDataDeleted(String s) throws Exception {
}
});
zkClient.writeData("/node11","node");
TimeUnit.SECONDS.sleep(2);
// watch机制,修改节点列表后触发
zkClient.subscribeChildChanges("/node11", new IZkChildListener() {
@Override
public void handleChildChange(String s, List<String> list) throws Exception {
System.out.println("节点名称:"+s+"->"+"当前的节点列表:"+list);
}
});
zkClient.delete("/node11/node1");;
TimeUnit.SECONDS.sleep(2);
}
}
三、apache的 curator
引入依赖
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.11.0</version>
</dependency>
public class CuratorOperatorDemo {
private final static String CONNECTSTRING="192.168.30.10:2181";
public static void main(String[] args) throws InterruptedException {
//创建会话的两种方式 normal
// CuratorFramework curatorFramework= CuratorFrameworkFactory.
// newClient(CONNECTSTRING,5000,5000,
// new ExponentialBackoffRetry(1000,3));
// curatorFramework.start(); //start方法启动连接
// //fluent风格
CuratorFramework curatorFramework=CuratorFrameworkFactory.builder().connectString(CONNECTSTRING).sessionTimeoutMs(5000).
retryPolicy(new ExponentialBackoffRetry(1000,3)).
build();
curatorFramework.start();
System.out.println("连接成功.........");
//fluent风格
/**
* 创建节点
*/
// try {
// String result=curatorFramework.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).
// forPath("/curator/curator1/curator11","123".getBytes());
//
// System.out.println(result);
// } catch (Exception e) {
// e.printStackTrace();
// }
/**
* 删除节点
*/
// try {
// //默认情况下,version为-1
// curatorFramework.delete().deletingChildrenIfNeeded().forPath("/curator");
//
// } catch (Exception e) {
// e.printStackTrace();
// }
/**
* 查询
*/
// Stat stat=new Stat();
// try {
// byte[] bytes=curatorFramework.getData().storingStatIn(stat).forPath("/node11");
// System.out.println(new String(bytes)+"-->stat:"+stat);
// } catch (Exception e) {
// e.printStackTrace();
// }
/**
* 更新
*/
// try {
// Stat stat=curatorFramework.setData().forPath("/node11","123".getBytes());
// System.out.println(stat);
// } catch (Exception e) {
// e.printStackTrace();
// }
/**
* 异步操作
*/
// ExecutorService service= Executors.newFixedThreadPool(1);
// CountDownLatch countDownLatch=new CountDownLatch(1);
// try {
// curatorFramework.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).
// inBackground(new BackgroundCallback() {
// @Override
// public void processResult(CuratorFramework curatorFramework, CuratorEvent curatorEvent) throws Exception {
// System.out.println(Thread.currentThread().getName()+"->resultCode:"+curatorEvent.getResultCode()+"->"
// +curatorEvent.getType());
// countDownLatch.countDown();
// }
// },service).forPath("/enjoy","deer".getBytes());
// } catch (Exception e) {
// e.printStackTrace();
// }
// countDownLatch.await();
// service.shutdown();
/**
* 事务操作(curator独有的)
*/
try {
Collection<CuratorTransactionResult> resultCollections=curatorFramework.inTransaction().create().forPath("/demo1","111".getBytes()).and().
setData().forPath("/demo1","111".getBytes()).and().commit();
for (CuratorTransactionResult result:resultCollections){
System.out.println(result.getForPath()+"->"+result.getType());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
事件监听方式
public class CuratorEventDemo {
/**
* 三种watcher来做节点的监听
* pathcache 监视一个路径下子节点的创建、删除、节点数据更新
* NodeCache 监视一个节点的创建、更新、删除
* TreeCache pathcaceh+nodecache 的合体(监视路径下的创建、更新、删除事件),
* 缓存路径下的所有子节点的数据
*/
public static void main(String[] args) throws Exception {
CuratorFramework curatorFramework=CuratorClientUtils.getInstance();
/**
* 节点变化NodeCache
*/
/* NodeCache cache=new NodeCache(curatorFramework,"/curator",false);
cache.start(true);
cache.getListenable().addListener(()-> System.out.println("节点数据发生变化,变化后的结果" +
":"+new String(cache.getCurrentData().getData())));
curatorFramework.setData().forPath("/curator","菲菲".getBytes());*/
/**
* PatchChildrenCache
*/
PathChildrenCache cache=new PathChildrenCache(curatorFramework,"/event",true);
cache.start(PathChildrenCache.StartMode.POST_INITIALIZED_EVENT);
// Normal / BUILD_INITIAL_CACHE /POST_INITIALIZED_EVENT
cache.getListenable().addListener((curatorFramework1,pathChildrenCacheEvent)->{
switch (pathChildrenCacheEvent.getType()){
case CHILD_ADDED:
System.out.println("增加子节点");
break;
case CHILD_REMOVED:
System.out.println("删除子节点");
break;
case CHILD_UPDATED:
System.out.println("更新子节点");
break;
default:break;
}
});
curatorFramework.create().withMode(CreateMode.PERSISTENT).forPath("/event","event".getBytes());
TimeUnit.SECONDS.sleep(1);
System.out.println("1");
curatorFramework.create().withMode(CreateMode.EPHEMERAL).forPath("/event/event1","1".getBytes());
TimeUnit.SECONDS.sleep(1);
System.out.println("2");
curatorFramework.setData().forPath("/event/event1","222".getBytes());
TimeUnit.SECONDS.sleep(1);
System.out.println("3");
curatorFramework.delete().forPath("/event/event1");
System.out.println("4");
System.in.read();
}
}