一、导入依赖
<dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.6</version> </dependency>
二、创建ZooKeeper对象
传入三个参数: ZooKeeper( String “ip地址:路径”, int 超时时间 , Watcher 事件监听) 。
CountDownLatch countDownLatch = new CountDownLatch(1); ZooKeeper zk = new ZooKeeper("localhost:2181", 3000, new Watcher() { @Override public void process(WatchedEvent event) { if(event.getState() == Event.KeeperState.SyncConnected){ countDownLatch.countDown(); } } }); countDownLatch.await();
三、创建节点
传入四个参数:String create(final String 节点路径, byte 节点数据,[], List acl集合,
CreateMode 节点类型)
示例: 创建一个/node1节点,数据为"data", acl为: world:anyone:cdrwa , 节点类型为持久类型。
zk.create("/node1","data".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE , CreateMode.PERSISTENT);
第三个参数 也可以这样创建,不用默认的ZooDefs.Ids中的acl,自己创建ACL实例 。
ACL实例需要传入 public ACL(int perms, org.apache.zookeeper.data.Id id)
List<ACL> acl = new ArrayListM<>(); ACL acl1 = new ACL(ZooDefs.Perms.ALL,new Id("world","anyone")); ACL acl2 = new ACL(31,new Id("ip","127.0.0.1")); acl.add(acl1): zk.create("/node1","data".getBytes(), acl , CreateMode.PERSISTENT);
其中第一个参数 ZooDefs.Perms.ALL
又可以传入数字。其实就是传入acl指令中的权限" rwcda" 。如我要选ALL的话就是二进制11111,转换成10进制就是31
数字的依据为:
//源码 public interface Perms { int READ = 1 << 0; int WRITE = 1 << 1; int CREATE = 1 << 2; int DELETE = 1 << 3; int ADMIN = 1 << 4; int ALL = READ | WRITE | CREATE | DELETE | ADMIN; }
四、判断节点是否存在
Stat exists(String path, boolean watch)
传入需要判断节点的路径,是否监听 。 会返回一个Stat对象,记录着当前节点的状态信息。如果节点不存在返回null
Stat对象内存有如下数据,可以在Stat对象通过getXXX()获取。
例如:
Stat s = zk.exists("/node1",false); if(s != null){ int version = s.getVersion(); long ctime = s.getCtime(); long mtime = s.getMtime(); }
五、删除节点
void delete(final String path, int version)
第一个参数是需要删除的节点的路径,第二个参数是删除节点的版本号,可以通过exist(path,false)来获取版本号。
示例:
zk.delete("/node1",zk.exists("node1",false).getVersion());
六、获取节点,并且绑定监听
获取节点数据:
调用如下方法:
public byte[] getData(final String path, Watcher watcher, Stat stat)
第一个参数传入节点路径,第二个参数传入监听 (可以设为null ),第三个参数传入Stat (可以设为null ) ,
示例:
byte [] ds = zk.getData("/node1" , null,null); System.out.println("/node1节点数据为 :"+new String(ds) +"");
监听: 可以通过获取节点数据来绑定监听。
1:直接在传入参数时new Watch对象
byte [] data = zk.getData("/node1", new Watcher() { @Override public void process(WatchedEvent event) { if( event.getType() == Event.EventType.NodeCreated ){ // 节点创建触发 System.out.println("节点创建触发"); }else if( event.getType() == Event.EventType.NodeDataChanged ){ // 节点数据被修改触发 System.out.println("节点数据被修改触发"); }else if(event.getType() == Event.EventType.NodeDeleted){ //节点被删除 System.out.println("节点被删除"); }else if( event.getType() == Event.EventType.NodeChildrenChanged){ //子节点被修改触发 System.out.println("子节点被修改触发"); } } } ,null);
2. 创建一个类继承Watch类
class MyWatcher implements Watcher{ @SneakyThrows @Override public void process(WatchedEvent event) { if( event.getType() == Event.EventType.NodeCreated ){ // 节点创建触发 System.out.println("节点创建触发"); }else if( event.getType() == Event.EventType.NodeDataChanged ){ // 节点数据被修改触发 System.out.println("节点数据被修改触发"); }else if(event.getType() == Event.EventType.NodeDeleted){ //节点被删除 System.out.println("节点被删除"); }else if( event.getType() == Event.EventType.NodeChildrenChanged){ //子节点被修改触发 System.out.println("子节点被修改触发"); } } }
使用
byte [] datas = zk.getData("/node1", new MyWatcher() ,null );
zk 为二中创建的ZooKeeper实例