• org.apache.zookeeper

  • org.apache.zookeeper.data

  • org.apache.zookeeper.server

  • org.apache.zookeeper.server.quorum

  • org.apache.zookeeper.server.upgrade

  • org.apache.zookeeper.server.upgrade.ZooKeeper //核心类

...upgrade.ZooKeeper

  • create()

  • delete()

  • exist()

  • getData()/setData()

  • getACL()/setACL() //访问控制列表

  • getChildren()

  • sync() //同步数据

ZooKeeper编程

  • 使用观察者创建zk实例,指定sess超时 //导入zk核心包和依赖
import java.io.IOException;

import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;

public class App {

    public static void main(String[] args) throws IOException, 
        KeeperException, InterruptedException {
        //异步建立连接,对象创建成果但不一定连接成功
        //连接串以node1:2181,node2:2181这样的形式
        //顺序连接,如果连接失败则连接下一个
        String connectString = "node2:2181";
        //超时时间为2s
        ZooKeeper zk = new ZooKeeper(connectString, 2000, null);
        //返回数据和给定路径上节点的状态
        //Stat类的字段和客户端的状态一一对应
        Stat stat = new Stat();
        byte[] bytes = zk.getData("/sss", null, stat);
        System.out.println(new String(bytes));
        System.out.println(stat.getAversion()); 
    }
}
  • 创建路径

acl : access control list,访问控制列表
控制权限

如果acl无效,为null或者为空会抛出KeeperException.InvalidACLException

MarshallingError是KeeperException.InvalidACLException的子类
public static void createPath() throws IOException, 
    KeeperException, InterruptedException{
        String connectString = "node2:2181";
        ZooKeeper zk = new ZooKeeper(connectString, 2000, null);
        //返回创建节点的真实路径
        //临时节点不能有孩子
        //zk已经把权限封装好了,不用自己去new这省的麻烦
        //zk提供了一个接口Ids,里面有封装好的acl的集合
        //CreateMode.PERSISTENT_SEQUENTIAL会在后面追加一个单调递增的后缀数字
        //EPHEMERAL为临时节点,断开连接自动删除
        String path = zk.create("/sss2", "123".getBytes(), 
                Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
        System.out.println(path);
    }
  • 删除路径
public static void deletePath() throws IOException, 
        InterruptedException, KeeperException{
        String connectString = "node2:2181";
        ZooKeeper zk = new ZooKeeper(connectString, 2000, null);
        //如果给定版本为-1则匹配任何版本
        //每个节点都用版本标识,相当于数据库的乐观锁(不懂),解决并发问题
        zk.delete("/sss20000000060", -1);
    }
  • 设置数据
public static void getData() throws IOException, 
        InterruptedException, KeeperException{
        String connectString = "node2:2181";
        ZooKeeper zk = new ZooKeeper(connectString, 2000, null);
        //版本与原来一致才能设置新值
        Stat stat = zk.setData("/sss2", "zzz".getBytes(), 0);
        System.out.println(stat.getVersion());
    }
  • 获取children
public static void getChildren() throws IOException, 
        InterruptedException, KeeperException{
        String connectString = "node2:2181";
        ZooKeeper zk = new ZooKeeper(connectString, 2000, null);
        List<String> children = zk.getChildren("/", null);
        for(String string:children){
            System.out.println(string);
        }
    }
  • 观察者watch,观察指定的事件

在一个程序中如果只剩下守护线程则程序结束

public static void watch() throws IOException, 
        InterruptedException, KeeperException{
        String connectString = "node2:2181";

        //启动一个线程来监听,所以可能主线程结束了它还没有监听到内容
        Watcher watcher = new Watcher() {

            @Override
            public void process(WatchedEvent event) {
                System.out.println("有人搞事情:"+event.getType());
            }
        };
        //注意:set方法只有状态回调,get方法才有watch回调
        ZooKeeper zk = new ZooKeeper(connectString, 1000, watcher);
        zk.getData("/sss2", watcher, null);
        zk.setData("/sss2", "搞事情".getBytes(), -1);
        zk.create("/sss3", "123".getBytes(), 
                Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
        zk.close();
        while(true){
            Thread.sleep(2000);
        }
    }