Java操作使用zookeeper

Zookeeper说明

创建节点方法

create:提供了两套创建节点的方法,同步和异步创建节点方式。

同步方式:

参数1,节点路径(名称) : InodeName (不允许递归创建节点,也就是说在父节点不存在
的情况下,不允许创建子节点)

参数2,节点内容: 要求类型是字节数组(也就是说,不支持序列化方式,如果需要实现序
列化,可使用java相关序列化框架,如Hessian、Kryo框架)

参數3,节点权限: 使用Ids.OPEN_ACL_UNSAFE开放权限即可。(这个参数一般在权展
没有太高要求的场景下,没必要关注)

参数4,节点类型: 创建节点的类型: CreateMode,提供四种节点类型

PERSISTENT 持久化节点
PERSISTENT_SEQUENTIAL 顺序自动编号持久化节点,这种节点会根据当前已存在的节点数自动加 1
EPHEMERAL 临时节点, 客户端session超时这类节点就会被自动删除
EPHEMERAL_SEQUENTIAL 临时自动编号节点

修改节点方法

setData
参数1,节点路径(名称) ;
参数2,节点内容;
参数3(version),version参数指定要更新的数据的版本, 如果version和真实的版本不同, 更新操作将失败. 指定version为-1则忽略版本检查

Maven依赖信息

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

Watcher

在ZooKeeper中,接口类Watcher用于表示一个标准的事件处理器,其定义了事件通知相关的逻辑,包含KeeperState和EventType两个枚举类,分别代表了通知状态和事件类型,同时定义了事件的回调方法:process(WatchedEvent event)。

什么是Watcher接口

同一个事件类型在不同的通知状态中代表的含义有所不同,下表列举了常见的通知状态和事件类型:
这里写图片描述
回调方法process()
process方法是Watcher接口中的一个回调方法,当ZooKeeper向客户端发送一个Watcher事件通知时,客户端就会对相应的process方法进行回调,从而实现对事件的处理。
process方法的定义如下:
abstract public void process(WatchedEvent event);
这个回调方法的定义非常简单,我们重点看下方法的参数定义:WatchedEvent。
WatchedEvent包含了每一个事件的三个基本属性:
通知状态(keeperState),事件类型(EventType)和节点路径(path),其数据结构如上图所示。ZooKeeper使用WatchedEvent对象来封装服务端事件并传递给Watcher,从而方便回调方法process对服务端事件进行处理。

代码实现

package com.wangys.test;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;

import java.io.IOException;
import java.util.concurrent.CountDownLatch;

/**
 * <p>Project: java-zookeeper</p>
 * <p>ClassName: BaseTest.java</p>
 * <p>Description: </p>
 * <p>CreateDate: 2018-09-03 上午11:47</p>
 * <p>Author: 王永圣</p>
 * <p>Version: 1.0.0</p>
 * <p>Copyright: Copyright(c) 2018</p>
 */
public class BaseTest implements Watcher{

    //连接地址
    private static final String ADDRESS = "127.0.0.1:2181";
    //session会话
    private static final Integer SESSION_TIMEOUT = 2000;
    //信号量,阻塞程序执行,用户必须等待zookeeper连接成功,发送成功信号
    private static final CountDownLatch COUNT_DOWN_LATCH = new CountDownLatch(1);

    private ZooKeeper zk;

    /**
     * 创建连接
     * @param address
     * @param sessionTimeout
     */
    public void createConnection(String address,Integer sessionTimeout){
        try {
           zk = new ZooKeeper(address,sessionTimeout,this);
           System.out.println("###zookeeper启动连接服务器###");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 事件处理
     * @param watchedEvent
     */
    @Override
    public void process(WatchedEvent watchedEvent) {
        //1、获取事件状态
        Event.KeeperState state = watchedEvent.getState();
        //2、获取事件类型
        Event.EventType type = watchedEvent.getType();
        //获取节点地址
        String path = watchedEvent.getPath();
        //3、判断是否连接
        if (Event.KeeperState.SyncConnected == state) {
            //4、判断类型
            if (Event.EventType.None == type) {
                /*try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }*/
                COUNT_DOWN_LATCH.countDown();
                System.out.println("###zookeeper建立连接成功###");
            } else if (Event.EventType.NodeCreated == type) {
                System.out.println("###Watcher监听的对应数据节点被创建###, 当前新增节点:"+path);
            } else if (Event.EventType.NodeDataChanged == type) {
                System.out.println("###Watcher监听的对应数据节点的数据内容发生变更###, 当前节点:"+path+",被修改...");
            } else if (Event.EventType.NodeChildrenChanged == type) {
                System.out.println("###Wather监听的对应数据节点的子节点列表发生变更###, 当前子节点:"+path+",被修改...");
            } else if (Event.EventType.NodeDeleted == type) {
                System.out.println("###Watcher监听的对应数据节点被删除###, 当前节点:"+path+",被删除...");
            }
        }
    }

    /**
     * 创建持久化节点
     * @param path
     * @param data
     */
    public boolean createNode(String path, String data){
        try {
            this.exists(path,true);
            //阻塞,当等于0的时候释放
            COUNT_DOWN_LATCH.await();
            zk.create(path,data.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
            System.out.println("###新增节点信息path:"+path+" data:"+data);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 修改持久化节点
     * @param path
     * @param data
     */
    public boolean updateNode(String path, String data){
        try {
            this.exists(path,true);
            //阻塞,当等于0的时候释放
            COUNT_DOWN_LATCH.await();
            //zk的数据版本是从0开始计数的。如果客户端传入的是-1,则表示zk服务器需要基于最新的数据进行更新。如果对zk的数据节点的更新操作没有原子性要求则可以使用-1.
            //version参数指定要更新的数据的版本, 如果version和真实的版本不同, 更新操作将失败. 指定version为-1则忽略版本检查
            zk.setData(path,data.getBytes(),-1);
            System.out.println("###修改节点信息path:"+path+" data:"+data);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除持久化节点
     * @param path
     */
    public boolean deleteNode(String path){
        try {
            this.exists(path,true);
            //阻塞,当等于0的时候释放
            COUNT_DOWN_LATCH.await();
            //version参数指定要更新的数据的版本, 如果version和真实的版本不同, 更新操作将失败. 指定version为-1则忽略版本检查
            zk.delete(path,-1);
            System.out.println("###删除节点信息path:"+path);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 判断指定节点是否存在
     * @param path
     * @param needWatch
     * @return
     */
    public Stat exists(String path, boolean needWatch){
        try {
            return this.zk.exists(path,needWatch);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 关闭服务
     */
    public void close(){
        try {
            if(zk!=null){
                System.out.println("###zookeeper服务已关闭");
                zk.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args){
        BaseTest test = new BaseTest();
        test.createConnection(ADDRESS,SESSION_TIMEOUT);
//        test.createNode("/yswKnight/wangys","wangYongsheng");
//        test.updateNode("/yswKnight/wangys","dasheng");
        test.deleteNode("/yswKnight/wangys");
        test.close();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值