zookeeper学习笔记-03


四 、java API

connect - 连接到ZooKeeper集合
create- 创建znode
exists- 检查znode是否存在及其信息
getData - 从特定的znode获取数据
setData - 在特定的znode中设置数据
getChildren - 获取特定znode中的所有子节点
delete - 删除特定的znode及其所有子项
close - 关闭连接
getACL 获取节点的ACL
setACL 设置节点的ACL

统一配置文件接口:

public interface IZooKeeperConfig {
    int PORT = 2181;
    String HOST = "192.168.220.132";
    String CONNECT_STRING = HOST + ":" + PORT;
}

1.创建会话(connect)

  • a).简单创建 — 第一个例子附上完整代码
private static CountDownLatch connectedSemaphore = new CountDownLatch(1);

public static void main(String[] args) throws IOException, InterruptedException {
    ZooKeeper zooKeeper = new ZooKeeper(IZooKeeperConfig.CONNECT_STRING, 5000, new MyWatcher()); 
    System.out.println(zooKeeper.getState()); //CONNECTING
    connectedSemaphore.await();  //因为是个异步的过程, 所以在这里增加一个信号
    System.out.println("zookeeper session 建立");
}

static class MyWatcher implements Watcher {
    @Override
    public void process(WatchedEvent event) {
        System.out.println("接收到event:"+event);
        if(event.getState() == Event.KeeperState.SyncConnected) {
            connectedSemaphore.countDown();
        }
    }
}
  • b).使用sid+password
long sessionid = zooKeeper.getSessionId();
byte[] passwd = zooKeeper.getSessionPasswd();
zooKeeper = new ZooKeeper(IZooKeeperConfig.CONNECT_STRING, 5000, new MyWatcher(),sessionid,passwd);

2.创建节点(create)

  • a).同步创建
String create(final String path, byte data[], List<ACL> acl,CreateMode createMode);
----------
path: 创建节点的路径
data[]: 字节数组,创建节点的数据
节点的ACL策略,通常用ZooDefs.Ids.OPEN_ACL_UNSAFE == rwcda
createMode: 等同于客户端 -s -e ,

    * EPHEMERAL , 临时节点
    * PERSISTENT, 持久节点
    * EPHEMERAL_SEQUENTIAL , 临时序列节点
    * PERSISTENT_SEQUENTIAL,持久序列节点

  • b).异步创建
void create(final String path, byte data[], List<ACL> acl,CreateMode createMode, StringCallback cb, Object ctx);
------------------------
ctx:    上下文
StringCallback:    注册一个异步的回调函数,需重写
void processResult(int rc, String path, Object ctx, String name); 方法
----- rc:    0:表示成功
        path:    创建路径
        ctx:    上下文
        name:    创建后的路径名称(当创建为**序列节点时,path != name)

3.删除节点(delete)

  • a).同步删除
delete(final String path, int version);
//---------------------
version:    节点数据版本,表示针对此版本的数据进行操作(可传-1,表示继续最新版本进行操作)
  • b).异步删除
delete(final String path, int version, VoidCallback cb,Object ctx);
//--------------
VoidCallback:    需要重写 void processResult(int rc, String path, Object ctx)方法;

事件类型:

  • NodeChildrenChanged: 仅仅在子节点列表发生变化时触发,自身数据发生变化,以及子节点数据发生变化都不触发。
  • NodeDataChanged: 仅仅在自身的数据发生变化时触发,当自身的子节点列表发生变化时也不触发。

4.获取子节点列表( getChildren )

  • a).同步获取子节点列表
getChildren(String path, boolean watch);
//---
watch: 表示是否使用默认的Watcher,此Watcher为创建连接时使用的Watcher.

----监听事件:NodeChildrenChanged
  • b).异步获取子节点列表
getChildren(String path, boolean watch, Children2Callback cb,Object ctx);
//---
AsyncCallback.Children2Callback : 注册一个异步回调函数需要重写:
void processResult(int rc, String path, Object ctx, List<String> children, Stat stat);
---children: 获取最新的子节点列表
---stat: 接收服务端新的stat.

5.获取节点数据( getData )

  • a).同步节点数据
byte[] getData(String path, boolean watch, Stat stat);
-----监听事件:NodeDataChanged
  • b).异步节点数据
void getData(String path, boolean watch, DataCallback cb, Object ctx);
//---
AsyncCallback.DataCallback:注册一个异步回调函数,需要重写:
void processResult(int rc, String path, Object ctx, byte data[],Stat stat);

6.更新数据(setData)
更新数据后,数据版号(dataversion)本会+1,即使更新前后数据一样,版本号仍然会+1

  • a).同步更新数据
setData(final String path, byte data[], int version) ;
//同delete
  • b).异步更新数据
void setData(final String path, byte data[], int version,StatCallback cb, Object ctx) 
//----
StatCallback :需重写:
void processResult(int rc, String path, Object ctx, Stat stat);

7.检验节点是否存在(exists)
监听事件类型:

  • NodeCreated: 节点新增
  • NodeDeleted: 节点删除
  • node的create,delete 并不会触发NodeChildrenChanged 和nodedatachanged事件。

  • a).同步更新数据

Stat exists(String path, boolean watch);
  • b).同步更新数据
void exists(String path, boolean watch, StatCallback cb, Object ctx);

8.权限控制( addAuthInfo )
java提供权限控制的api方法:addAuthInfo(Schema , byte[] auth):
Schema:权限控制模式分为:world, auth, digest, ip 和 super;
auth: 具体的权限信息;

当为zookeeper会话添加权限信息后,之后凡是通过该会话对Zookeeper服务端进行的操作都会加上该权限信息,否则抛出异常:org.apache.zookeeper.KeeperException$NoAuthException: KeeperErrorCode = NoAuth for /auth_test

zooKeeper1.addAuthInfo("digest","foo:true".getBytes());//zookeeper1使用加密; 
zooKeeper1.create(path, "jiami".getBytes(), ZooDefs.Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT_SEQUENTIAL); //该节点自动加上了授权信息,之后访问该节点必须加上该权限控制信息

特殊点:delete,

ZooKeeper zooKeeper1 = new ZooKeeper(IZooKeeperConfig.CONNECT_STRING, 5000, new MyWatcher());
ZooKeeper zooKeeper2 = new ZooKeeper(IZooKeeperConfig.CONNECT_STRING, 5000, new MyWatcher());
ZooKeeper zooKeeper3 = new ZooKeeper(IZooKeeperConfig.CONNECT_STRING, 5000, new MyWatcher());
ZooKeeper zooKeeper4 = new ZooKeeper(IZooKeeperConfig.CONNECT_STRING, 5000, new MyWatcher());

zooKeeper1.addAuthInfo("digest","foo:true".getBytes());
zooKeeper1.create("/a", "a".getBytes(), ZooDefs.Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
System.out.println("加密创建a成功");
try{
    zooKeeper2.getData("/a", false, null); //报错
}catch (Exception e) {
    System.out.println("getData失败");//失败
}

try{
    zooKeeper3.create("/a/b", "b".getBytes(), ZooDefs.Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
}catch (Exception e) {
    System.out.println("创建子节点/a/b失败");// 失败
}
zooKeeper4.delete("/a",-1);
System.out.println("删除/a成功");
zooKeeper1.create("/a", "a".getBytes(), ZooDefs.Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
zooKeeper1.create("/a/b", "b".getBytes(), ZooDefs.Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
try{
    zooKeeper4.delete("/a/c",-1); //失败
}catch (Exception e) {
    System.out.println("删除/a/c失败");// 失败
}

打印结果为:

加密创建a成功
getData失败
创建子节点/a/b失败
删除/a成功
删除/a/c失败

总结:针对于delete,授权信息是针对于该节点的子节点的,不影响对该节点本身的删除.

猜你喜欢

转载自blog.csdn.net/it_freshman/article/details/79262191