• zookeeper的Java客户端API


    zookeeper作为一个分布式服务框架,主要用来解决分布式数据一致性问题,对多种语言提供了API。这里主要记录下JAVA客户端API的使用。

    1.创建会话

    客户端可以通过创建一个ZooKeeper实例来连接zookeeper服务器

    ZooKeeper的4个构造函数如下:

    [java] view plain copy
     
    1. ZooKeeper(connectString, sessionTimeout, watcher);  
    2. ZooKeeper(connectString, sessionTimeout, watcher,canBeReadOnly);  
    3. ZooKeeper(connectString, sessionTimeout, watcher, sessionId, sessionPasswd);  
    4. ZooKeeper(connectString, sessionTimeout, watcher, sessionId, sessionPasswd, canBeReadOnly);  
    
    
    

    参数说明:

    connectString: 连接字符串 例如 "127.0.0.1:2181"

    sessionTimeout: 会话超时时间 以毫秒为单位的整型值 在sessionTimeout时间内服务端与客户端没有有效的心跳检测 则会话失效

    watcher: 默认的事件通知处理器

    sessionId: 会话ID

    sessionPasswd: 会话秘钥

    canBeReadOnly: 是否是只读  

          

    [java] view plain copy
     
    1. public class ZookeeperSampleTest implements Watcher {  
    2.   
    3.     private static CountDownLatch connectedSemaphore = new CountDownLatch(1);  
    4.       
    5.     public static void main(String args[]) throws IOException, InterruptedException{  
    6.         ZooKeeper zk = new ZooKeeper("192.168.1.138:2181",5000,new ZookeeperSampleTest());  
    7.         System.out.println(zk.getState());  
    8.         try {  
    9.             connectedSemaphore.await();  
    10.         } catch (Exception e) {  
    11.             // TODO: handle exception  
    12.         }  
    13.         Long sessionId = zk.getSessionId();  
    14.         byte[] password = zk.getSessionPasswd();  
    15.         zk = new ZooKeeper("192.168.1.138:2181",5000,new ZookeeperSampleTest(),1L,"test".getBytes());  
    16.         zk = new ZooKeeper("192.168.1.138:2181",5000,new ZookeeperSampleTest(),sessionId,password);  
    17.         Thread.sleep(Integer.MAX_VALUE);  
    18.         //System.out.println("ZooKeeper session established");  
    19.     }  
    20.   
    21.     @Override  
    22.     public void process(WatchedEvent event) {  
    23.         // TODO Auto-generated method stub  
    24.         System.out.println("Receive watched event :" + event);  
    25.         if(event.getState()==KeeperState.SyncConnected){  
    26.             connectedSemaphore.countDown();  
    27.         }  
    28.     }  
    29.   
    30. }  

    2.创建节点

    创建节点的方式分为同步和异步,构造函数如下:

    [java] view plain copy
     
    1. zk.create(path, data, acl, createMode);  
    2. , data, acl, createMode, cb, ctx);  

    参数说明:

    path: 创建节点的路径 如:/zk-test

    data[]: 字节数组,节点数据

    acl: 权限  

    createMode: 节点类型  分为4种: 持久性节点,持久性有序节点,临时节点,临时有序节点

    cb: 回调函数 需要实现StringCallback接口

    ctx: 上下文 一般用于回调函数时候使用

    [java] view plain copy
     
    1. public class ZookeeperSampleCreateTest implements Watcher {  
    2.   
    3.     public static CountDownLatch connectedSemaphore = new CountDownLatch(1);  
    4.       
    5.     public static void main(String[] args) throws IOException, InterruptedException, KeeperException{  
    6.         ZooKeeper zk = new ZooKeeper("192.168.1.138:2181",5000,new ZookeeperSampleCreateTest());  
    7.         connectedSemaphore.await();  
    8.         /*同步的方式*/  
    9.         /*String path1 = zk.create("/zk-test-ephemeral-", "test-ephemeral".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL); 
    10.         System.out.println("Success create node :" + path1); 
    11.         String path2 = zk.create("/zk-test-ephemeral-", "test-ephemeral-sequential".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL); 
    12.         System.out.println("Success create node :" + path2);*/  
    13.           
    14.         /*异步的方式*/  
    15.         zk.create("/zk-test-ephemeral-", "".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL,new IStringCallback(),"i am context");  
    16.         zk.create("/zk-test-ephemeral-", "".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL,new IStringCallback(),"i am context");  
    17.         zk.create("/zk-test-ephemeral-", "".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL,new IStringCallback(),"i am context");  
    18.         Thread.sleep(Integer.MAX_VALUE);  
    19.     }  
    20.       
    21.     @Override  
    22.     public void process(WatchedEvent event) {  
    23.         // TODO Auto-generated method stub  
    24.         if(KeeperState.SyncConnected == event.getState()){  
    25.             connectedSemaphore.countDown();  
    26.         }  
    27.     }  
    28. }  
    29.   
    30. class IStringCallback implements AsyncCallback.StringCallback{  
    31.   
    32.     @Override  
    33.     public void processResult(int rc, String path, Object ctx, String name) {  
    34.         // TODO Auto-generated method stub  
    35.         System.out.println("Create path result: [" + rc + "," + path + "," + ctx + ", real path name " + name);  
    36.     }  
    37.       
    38. }  

    3.删除节点

    [java] view plain copy
     
    1. zk.delete(path,version);  
    2. zk.delete(path,version,cb,ctx);  

    参数说明:

    path:节点路径

    version:版本号

    cb: 回调函数

    ctx: 上下文

    4.获取子节点

    getChildren有8个重载方法

    [java] view plain copy
     
    1.               zk.getChildren(path, watch);  
    2. zk.getChildren(path, watcher);  
    3. zk.getChildren(path, watch, stat);  
    4. zk.getChildren(path, watcher, stat);  
    5. zk.getChildren(path, watch, cb, ctx);  
    6. zk.getChildren(path, watcher, cb, ctx);  

    其中 回调函数有两种  ChildrenCallback  Children2Callback

    参数说明:

    path:节点路径

    watch: boolean类型 如果为true 表示使用默认的Watcher 为false表示不需要Watcher

    watcher: 通知处理器 在本次获取子节点以后  一旦子节点有变化机会收到服务端传来的通知

    stat: 指定数据节点的节点状态信息,传入一个旧的stat对象,当执行方法后 stat会被服务器响应的新stat替换

    cb:回调函数 有两种类型 上面已经说过

    ctx: 上下文

     5.获取节点数据

    获取节点数据有4个重载方法

    [java] view plain copy
     
    1.               zk.getData(path, watch, stat);  
    2. zk.getData(path, watcher, stat);  
    3. zk.getData(path, watch, cb, ctx);  
    4. zk.getData(path, watcher, cb, ctx);  

    参数说明:

    path: 节点路径

    watch: boolean类型 如果为true 表示使用默认的Watcher 为false表示不需要Watcher

    stat: 指定数据节点的节点状态信息,传入一个旧的stat对象,当执行方法后 stat会被服务器响应的新stat替换

    cb:回调函数 有两种类型 上面已经说过

    ctx: 上下文

    在获取节点数据时候 如果注册watcher 在节点数据发送变化的时候会通知客户端,当客户端收到通知以后,如果想下次数据发送变化再次收到通知,

    需要重新注册watcher,获取子节点机制也如此

    6.更新节点数据

    更新节点数据也分为同步异步两个方法

    [java] view plain copy
     
    1. zk.setData(path, data, version);  
    2. zk.setData(path, data, version, cb, ctx);  

    参数说明:同上

    [java] view plain copy
     
    1. public class ZookeeperSampleGetDataTest implements Watcher {  
    2.   
    3.     public static CountDownLatch connectedSemaphore = new CountDownLatch(1);  
    4.       
    5.     public static Stat stat = new Stat();  
    6.       
    7.     public static ZooKeeper zk = null;  
    8.       
    9.     public static void main(String[] args) throws IOException, KeeperException, InterruptedException{  
    10.         String path = "/zk-test";  
    11.         zk = new ZooKeeper("192.168.1.138:2181", 5000, new ZookeeperSampleGetDataTest());  
    12.         connectedSemaphore.await();  
    13.           
    14.         //获取子节点  
    15.         /*zk.delete(path, 0); 
    16.         zk.create(path, "".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); 
    17.         zk.create(path+"/c1", "".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL); 
    18.         //同步方法获取children 
    19.         //List<String> childs = zk.getChildren(path, true); 
    20.         //System.out.println(childs); 
    21.         //异步方法获取children 
    22.         zk.getChildren(path, true, new IChildren2Callback(), null); 
    23.          
    24.         zk.create(path+"/c2", "".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL); 
    25.         Thread.sleep(Integer.MAX_VALUE);*/  
    26.         //获取节点数据  
    27.         zk.delete(path, 0);  
    28.         zk.create(path, "123".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);  
    29.           
    30.         System.out.println(new String(zk.getData(path, true, stat)));  
    31.         /** czxid: 创建该节点的事务ID  mzxid: 更新该节点的事务ID  version: 数据版本*/  
    32.         System.out.println("Czxid: " + stat.getCzxid() + "Mzxid: " + stat.getMzxid() + "Version: " + stat.getVersion());  
    33.           
    34.         zk.setData(path, "123".getBytes(), -1);  
    35.           
    36.         Thread.sleep(Integer.MAX_VALUE);  
    37.     }  
    38.       
    39.       
    40.     @Override  
    41.     public void process(WatchedEvent event) {  
    42.         // TODO Auto-generated method stub  
    43.         if(KeeperState.SyncConnected==event.getState()){  
    44.             if(EventType.None==event.getType() && null==event.getPath()){  
    45.                 connectedSemaphore.countDown();  
    46.             }else if(event.getType()==EventType.NodeChildrenChanged){  
    47.                 try {  
    48.                     System.out.println("Get Child :" + zk.getChildren(event.getPath(), true));  
    49.                 } catch (KeeperException | InterruptedException e) {  
    50.                     // TODO Auto-generated catch block  
    51.                     e.printStackTrace();  
    52.                 }  
    53.             }else if(event.getType()==EventType.NodeDataChanged){  
    54.                 try {  
    55.                     System.out.println(new String(zk.getData(event.getPath(), true, stat)));  
    56.                     System.out.println("Czxid: " + stat.getCzxid() + "Mzxid: " + stat.getMzxid() + "Version: " + stat.getVersion());  
    57.                 } catch (KeeperException | InterruptedException e) {  
    58.                     // TODO Auto-generated catch block  
    59.                     e.printStackTrace();  
    60.                 }  
    61.             }      
    62.         }  
    63.     }  
    64. }  
    65.   
    66. class IChildren2Callback implements AsyncCallback.Children2Callback{  
    67.   
    68.     @Override  
    69.     public void processResult(int rc, String path, Object ctx,  
    70.             List<String> childrens, Stat stat) {  
    71.         // TODO Auto-generated method stub  
    72.         System.out.println("Get Children znode result: [response code: " + rc + ", param path: " + path + ", ctx " + ctx  
    73.                 + ", childrens :" +  childrens + ", stat: " + stat);  
    74.     }  
    75.       
    76. }  

    其中更新节点数据 版本version问题 -1表示基于数据的最新版本更新 这里可以作为分布式锁的一个思路 如果客户端参入的version不是数据最新版本则会更新失败

    比如目前节点"/zk-test"的数据版本为 2 而某个客户端尝试 执行 setData("/zk-test","test".getBytes(),1) 由于传入version为1 < 服务器目前版本2 这样就会更新失败

    7.检测节点是否存在

    [java] view plain copy
     
    1.               zk.exists(path, watch);  
    2. zk.exists(path, watcher);  
    3. zk.exists(path, watch, cb, ctx);  
    4. zk.exists(path, watcher, cb, ctx);  

    如果判断节点是否存在是 注册watcher 会对节点是否存在进行监听--创建节点,删除节点,节点数据更新都会通知客户端

    8.权限控制

    zookeeper提供了ACL的权限控制机制,简单来说就是通过控制zookeeper服务器上数据节点的ACL,来控制客户端对节点的访问权限

    [java] view plain copy
     
    1. addAuthInfo(String scheme,byte[] auth);  

    参数说明:

    scheme: 权限控制模式 分为: world ,auth,digest,ip和super

    auth: 具体的权限信息  类似于shiro的权限字符串

    如下代码:

    [java] view plain copy
     
    1. <span style="white-space:pre;">     </span>ZooKeeper zk1 = new ZooKeeper("192.168.1.138:2181",5000,new ZookeeperSampleCreateTest());  
    2.         zk1.addAuthInfo("digest", "test:true".getBytes());  
    3.         zk1.create("/zk-test-auth", "123".getBytes(), Ids.CREATOR_ALL_ACL, CreateMode.EPHEMERAL);  
    4.         ZooKeeper zk2 = new ZooKeeper("192.168.1.138:2181",5000,new ZookeeperSampleCreateTest());  
    5.         zk2.addAuthInfo("digest", "test:true".getBytes());  
    6.         System.out.println(new String(zk2.getData("/zk-test-auth", false, null)));  
    7.         ZooKeeper zk3 = new ZooKeeper("192.168.1.138:2181",5000,new ZookeeperSampleCreateTest());  
    8.         zk3.addAuthInfo("digest", "test:false".getBytes());  
    9.         zk3.getData("/zk-test-auth", false, null);  

    zk2设置了正确的权限 所以可以获取到节点数据  zk3则会抛异常

     org.apache.zookeeper.KeeperException$NoAuthException: KeeperErrorCode = NoAuth for /zk-test-auth

  • 相关阅读:
    IE6 跟随滚动解决方法
    CentOS 7 用户怎样安装 LNMP(Nginx+PHP+MySQL)
    [ConcurrencyCheck]并发检查
    centos7下修改docker工作目录
    kubernetes 1.14安装部署helm插件
    kubernetes 1.14安装部署EFK日志收集系统
    kubernetes 1.14安装部署dashboard
    kubernetes 1.14安装部署metrics-server插件
    calico客户端工具calicoctl
    centos7使用kubeadm安装部署kubernetes 1.14
  • 原文地址:https://www.cnblogs.com/cxxjohnson/p/9121709.html
Copyright © 2020-2023  润新知