Zookeeper(3)javaAPI

252 阅读6分钟

zookeeper提供了javaAPI。方便java代码集成zookeeper的相关应用

Zookeeper客户端的特点:

  • 连接到zookeeper服务器。zookeeper服务器为客户端分配会话ID。
  • 定期向服务器发送心跳。否则,zookeeper服务器将过期会话ID,客户端需要重新连接。
  • 只要会话ID处于活动状态,就可以获取/设置znode。
  • 所有任务完成后,断开与zookeeper服务器的连接。如果客户端长时间不活动,则zookeeper服务器将自动断开客户端。

1.Zookeeper maven依赖

<dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.6</version>
</dependency>

2.ZookeeperAPI的基本用法

(一)链接到Zookeeper

ZooKeeper(String connectionString, int sessionTimeout, Watcher watcher)

- connectionString - zookeeper主机--127.0.0.1:2181
- sessionTimeout - 会话超时(以毫秒为单位)
- watcher - 实现“监视器”对象。zookeeper集合通过监视器对象返回连接状态。
public class c01连接到Zookeeper {
    public static void main(String[] args) {
        ZooKeeper zooKeeper = null;
        try {
            // 计数器对象
            CountDownLatch countDownLatch = new CountDownLatch(1);
            // arg1:服务器的ip和端口
            // arg2:客户端与服务器之间的会话超时时间以毫秒为单位的
            // arg3:监视器对象
            zooKeeper = new ZooKeeper("192.168.72.128:2181", 5000, new Watcher() {
                @Override
                public void process(WatchedEvent event) {
                    if (event.getState() == Event.KeeperState.SyncConnected) {
                        System.out.println("连接创建成功!");
                        countDownLatch.countDown();
                    }
                }
            });
            // 主线程阻塞等待连接对象的创建成功
            countDownLatch.await();
            // 会话编号
            System.out.println(zooKeeper.getSessionId());

        } catch (Exception ex) {
            ex.printStackTrace();
        }finally {
            if (zooKeeper != null) {
                try {
                    zooKeeper.close();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

(二)新增节点

// 同步方式
create(String path, byte[] data, List<ACL> acl, CreateMode createMode)
// 异步方式
create(String path, byte[] data, List<ACL> acl, CreateMode createMode,AsyncCallback.StringCallback callBack,Object ctx)

-path - znode路径。例如,/node1 /node1/node11
-data - 要存储在指定znode路径中的数据
-acl - 要创建的节点的访问控制列表。zookeeper API提供了一个静态接口
-ZooDefs.Ids 来获取一些基本的acl列表。例如,ZooDefs.Ids.OPEN_ACL_UNSAFE返回打开znode的acl列表。
-createMode - 节点的类型,这是一个枚举。
-callBack-异步回调接口
-ctx-传递上下文参数
public class c02新增节点 {
    String IP="192.168.72.128:2181";
    ZooKeeper zooKeeper;

    @Before
    public void before() {
        try {
            // 计数器对象
            CountDownLatch countDownLatch=new CountDownLatch(1);
            // arg1:服务器的ip和端口
            // arg2:客户端与服务器之间的会话超时时间以毫秒为单位的
            // arg3:监视器对象
            zooKeeper=new ZooKeeper(IP, 5000, new Watcher() {
                @Override
                public void process(WatchedEvent event) {
                    if(event.getState()==Event.KeeperState.SyncConnected) {
                        System.out.println("连接创建成功!");
                        countDownLatch.countDown();
                    }
                }
            });
            // 主线程阻塞等待连接对象的创建成功
            countDownLatch.await();
        }catch (Exception e) {
            System.out.println("创建连接出现异常:"+e);
        }
    }

    @After
    public void after() {
        if( zooKeeper != null) {
            try {
                zooKeeper.close();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Test
    public void 创建节点1() throws KeeperException, InterruptedException {
        zooKeeper.create("/create/node1","node1".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        System.out.println("创建节点成功");
    }

    @Test
    public void 创建节点2() throws KeeperException, InterruptedException {
        zooKeeper.create("/create/node2","node2".getBytes(), ZooDefs.Ids.READ_ACL_UNSAFE, CreateMode.PERSISTENT);
        System.out.println("创建节点成功");
    }

    @Test
    public void 创建节点3() throws KeeperException, InterruptedException {
        //world模式
        List<ACL> acls = new ArrayList<ACL>();
        Id id = new Id("world","anyone");
        acls.add(new ACL(ZooDefs.Perms.READ, id));
        acls.add(new ACL(ZooDefs.Perms.WRITE, id));
        String s = zooKeeper.create("/create/node3", "node3".getBytes(), acls, CreateMode.PERSISTENT);
        System.out.println("创建节点成功:"+s);
    }

    @Test
    public void 创建节点4() throws KeeperException, InterruptedException {
        //ip授权模式
        List<ACL> acls = new ArrayList<ACL>();
        Id id = new Id("ip","100.5.81.208");
        acls.add(new ACL(ZooDefs.Perms.READ, id));
        acls.add(new ACL(ZooDefs.Perms.WRITE, id));
        String s = zooKeeper.create("/create/node4", "node4".getBytes(), acls, CreateMode.PERSISTENT);
        System.out.println("创建节点成功:"+s);
    }

    @Test
    public void 创建节点5() throws KeeperException, InterruptedException {
        //digest授权模式
        zooKeeper.addAuthInfo("digest","123456".getBytes());
        String s = zooKeeper.create("/create/node5", "node5".getBytes(), ZooDefs.Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
        System.out.println("创建节点成功:"+s);
    }

    @Test
    public void 创建节点6() throws KeeperException, InterruptedException {
        //auth授权模式
        List<ACL> acls = new ArrayList<ACL>();
        zooKeeper.addAuthInfo("digest","author:123456".getBytes());
        Id id = new Id("auth","author");
        acls.add(new ACL(ZooDefs.Perms.READ, id));
        acls.add(new ACL(ZooDefs.Perms.WRITE, id));
        String s = zooKeeper.create("/create/node666", "node666".getBytes(), acls, CreateMode.PERSISTENT);
        System.out.println("创建节点成功:"+s);
    }

    @Test
    public void 创建节点7() throws KeeperException, InterruptedException {
        //digest授权模式
        List<ACL> acls = new ArrayList<ACL>();
        zooKeeper.addAuthInfo("digest","author:123456".getBytes());
        //注意,此处的访问控制列表中的密码一定要是经过SHA1及BASE64处理的密文,否则使用"author:123456"无法获取
        Id id = new Id("digest","author:Wktc0WylCtNWzCgu94EY5ddV18E=");
        acls.add(new ACL(ZooDefs.Perms.ALL, id));
        String s = zooKeeper.create("/create/nodeCode", "nodeCode".getBytes(), acls, CreateMode.PERSISTENT);
        System.out.println("创建节点成功:"+s);
    }

    @Test
    public void 创建节点8() throws KeeperException, InterruptedException {
        //创建序列化节点
        String s = zooKeeper.create("/create/node8", "node8".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
        System.out.println("创建节点成功"+s);
    }

    @Test
    public void 创建节点9() throws KeeperException, InterruptedException {
        //创建临时节点
        String s = zooKeeper.create("/create/node9", "node9".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
        System.out.println("创建节点成功"+s);
    }

    @Test
    public void 创建节点10() throws KeeperException, InterruptedException {
        //创建节点,异步回调
        zooKeeper.create("/create/node10", "node10".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT, new AsyncCallback.StringCallback() {
            @Override
            public void processResult(int rc, String path, Object ctx, String name) {
                // 0 代表创建成功
                System.out.println(rc);
                //节点的路径
                System.out.println(path);
                //节点的路经
                System.out.println(name);
                //节点的上下文信息
                System.out.println(ctx);

            }
        },"I am Context");
        System.out.println("创建节点成功");
    }
}

SHA1及BASE64处理的密文计算函数

public class c06密码转化 {
    public static void main(String[] args) throws NoSuchAlgorithmException {
        String usernameAndPassword = "author:123456";
        byte digest[] = MessageDigest.getInstance("SHA1").digest(usernameAndPassword.getBytes());
        Base64 base64 = new Base64();
        String encodeToString = base64.encodeToString(digest);
        System.out.println(encodeToString);
    }
}

(三)更新节点

// 同步方式
setData(String path, byte[] data, int version)
// 异步方式
setData(String path, byte[] data, int version,AsyncCallback.StatCallBack, Object ctx)

path- znode路径
data - 要存储在指定znode路径中的数据。
version- znode的当前版本。每当数据更改时,ZooKeeper会更新znode的版本号。
callBack-异步回调接口
ctx-传递上下文参数
@Test
    public void 更新节点1() throws KeeperException, InterruptedException {
        Stat stat1 = new Stat();
        byte[] data = zooKeeper.getData("/create/node1", false, stat1);
        System.out.println(new String(data));
        System.out.println(stat1.getVersion());
        Stat stat = zooKeeper.setData("/create/node1", "node11".getBytes(), stat1.getVersion());
        System.out.println(stat.getVersion());
        System.out.println(stat.getCtime());
        System.out.println("更新节点成功");
    }

    @Test
    public void 更新节点2() throws KeeperException, InterruptedException {
        //异步更新节点
        Stat stat1 = new Stat();
        byte[] data = zooKeeper.getData("/create/node3", false, stat1);
        System.out.println(new String(data));
        System.out.println(stat1.getVersion());
        zooKeeper.setData("/create/node3", "node44".getBytes(), stat1.getVersion(), new AsyncCallback.StatCallback() {
            @Override
            public void processResult(int rc, String path, Object ctx, Stat stat) {
                System.out.println(rc);
                System.out.println(path);
                System.out.println(ctx);
                System.out.println(stat.getVersion());
            }
        },"i am context");

        System.out.println("更新节点成功");
    }

(四)删除节点

// 同步方式
delete(String path, int version)
// 异步方式
delete(String path, int version, AsyncCallback.VoidCallback callBack,Object ctx)

path - znode路径。
version - znode的当前版本
callBack-异步回调接口
ctx-传递上下文参数
 @Test
    public void 删除节点1() throws KeeperException, InterruptedException {
        Stat stat1 = new Stat();
        byte[] data = zooKeeper.getData("/create/node1", false, stat1);
        System.out.println(new String(data));
        System.out.println(stat1.getVersion());
        zooKeeper.delete("/create/node1",stat1.getVersion());
        System.out.println("删除节点成功");
    }

    @Test
    public void 删除节点2() throws KeeperException, InterruptedException {
        //异步删除节点
        Stat stat1 = new Stat();
        byte[] data = zooKeeper.getData("/create/node2", false, stat1);
        System.out.println(new String(data));
        System.out.println(stat1.getVersion());
        zooKeeper.delete("/create/node2",stat1.getVersion(), new AsyncCallback.VoidCallback() {
            @Override
            public void processResult(int rc, String path, Object ctx) {
                System.out.println(rc);
                System.out.println(path);
                System.out.println(ctx);
            }
        },"i am context");

        System.out.println("更新节点成功");
    }

(五)查看节点

// 同步方式
getData(String path, boolean b, Stat stat)
// 异步方式
getData(String path, boolean b,AsyncCallback.DataCallback callBack,Object ctx)

path - znode路径。
b- 是否使用连接对象中注册的监视器。
stat - 返回znode的元数据。
callBack-异步回调接口
ctx-传递上下文参数
@Test
    public void 查看节点1() throws KeeperException, InterruptedException {
        Stat stat1 = new Stat();
        zooKeeper.addAuthInfo("digest","author:123456".getBytes());
        byte[] data = zooKeeper.getData("/create/nodeCode", false, stat1);
        System.out.println(new String(data));
        System.out.println(stat1.getVersion());
        System.out.println("查看节点成功");
    }

    @Test
    public void 查看节点2() throws KeeperException, InterruptedException {
        //异步查看节点
       zooKeeper.getData("/create/node3", true, new AsyncCallback.DataCallback() {
           @Override
           public void processResult(int rc, String path, Object ctx, byte[] data, Stat stat) {
               System.out.println(rc);
               System.out.println(ctx);
               System.out.println(new String(data));
               System.out.println(stat.getVersion());
           }
       },"i am context");
        System.out.println("查看节点成功");
    }

(六)查看子节点

// 同步方式
getChildren(String path, boolean b)
// 异步方式
getChildren(String path, boolean b,AsyncCallback.ChildrenCallBack,Object ctx)

path - Znode路径。
b- 是否使用连接对象中注册的监视器。
callBack - 异步回调接口。
ctx-传递上下文参数
  @Test
    public void 查看子节点1() throws KeeperException, InterruptedException {
        //异步查看节点
        List<String> children = zooKeeper.getChildren("/create", true);
        System.out.println(children);
        System.out.println("查看节点成功");
    }

    @Test
    public void 查看子节点2() throws KeeperException, InterruptedException {
        //异步查看节点
        zooKeeper.getChildren("/create", true, new AsyncCallback.Children2Callback() {
            @Override
            public void processResult(int rc, String path, Object ctx, List<String> children,Stat stat) {
                System.out.println(rc);
                System.out.println(path);
                System.out.println(ctx);
                System.out.println(children);
            }
        },"i am context");
        System.out.println("查看节点成功");
    }

(七)检查节点是否存在

// 同步方法
exists(String path, boolean b)
// 异步方法
exists(String path, boolean b,AsyncCallback.StatCallback callBack,Object ctx)

如果节点不存在,返回为空
- path- znode路径。
- b- 是否使用连接对象中注册的监视器。
- callBack - 异步回调接口。
- ctx-传递上下文参数

    @Test
    public void 查看节点是否存在1() throws KeeperException, InterruptedException {

        Stat exists = zooKeeper.exists("/create/node1", false);
        if (exists == null) {
            System.out.println("znode is not exists");
        }
        System.out.println("查看节点");
    }

    @Test
    public void 查看节点是否存在2() throws KeeperException, InterruptedException {

        zooKeeper.exists("/create/node1", false, new AsyncCallback.StatCallback() {
            @Override
            public void processResult(int rc, String path, Object ctx, Stat stat) {
                System.out.println(stat);
            }
        },"i am context");
        System.out.println("查看节点");
    }