06. zookeeper原生java api使用

本文介绍了ZooKeeper客户端如何连接服务器并建立会话,包括单机和集群环境下的连接方式,以及会话的恢复过程。同时,还详细讲解了通过ZooKeeper API进行节点的创建、删除、数据修改及查询等基本操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

会话连接与恢复

会话连接

public class ZKConnect implements Watcher{

    private final static  Logger log = LoggerFactory.getLogger(ZKConnect.class);

//    private static final String zkServerPath = "192.168.1.53:2181";
    private static final String zkServerPath = "192.168.1.53:2181,192.168.1.54:2181,192.168.1.55:2181";

    private static final Integer timeout = 5000;

    public static void main(String[] args) throws IOException, InterruptedException {
        /**
         * 客户端和zk服务端链接是一个异步的过程
         * 当连接成功后后,客户端会收的一个watch通知
         *
         * 参数:
         * connectString:连接服务器的ip字符串,
         * 		比如: "192.168.1.1:2181,192.168.1.2:2181,192.168.1.3:2181"
         * 		可以是一个ip,也可以是多个ip,一个ip代表单机,多个ip代表集群
         * 		也可以在ip后加路径
         * sessionTimeout:超时时间,心跳收不到了,那就超时
         * watcher:通知事件,如果有对应的事件触发,则会收到一个通知;如果不需要,那就设置为null
         * canBeReadOnly:可读,当这个物理机节点断开后,还是可以读到数据的,只是不能写,
         * 					       此时数据被读取到的可能是旧数据,此处建议设置为false,不推荐使用
         * sessionId:会话的id
         * sessionPasswd:会话密码	当会话丢失后,可以依据 sessionId 和 sessionPasswd 重新获取会话
         */
        ZooKeeper zooKeeper = new ZooKeeper(zkServerPath, timeout, new ZKConnect());

        log.warn("客户端开始连接zookeeper服务器...");
        log.warn("连接状态:{}", zooKeeper.getState());
        new Thread().sleep(2000);
        log.warn("连接状态:{}", zooKeeper.getState());
    }


    public void process(WatchedEvent watchedEvent) {
        log.warn("接收到watch通知:{}",watchedEvent);
    }
}

控制台输出

2018-04-20 13:35:04,408 [main] [com.zj.zookeeperStudy.ZKConnect.main(ZKConnect.java:23)] - [WARN] 客户端开始连接zookeeper服务器...
2018-04-20 13:35:04,416 [main] [com.zj.zookeeperStudy.ZKConnect.main(ZKConnect.java:24)] - [WARN] 连接状态:CONNECTING
2018-04-20 13:35:04,506 [main-EventThread] [com.zj.zookeeperStudy.ZKConnect.process(ZKConnect.java:31)] - [WARN] 接收到watch通知:WatchedEvent state:SyncConnected type:None path:null
2018-04-20 13:35:06,417 [main] [com.zj.zookeeperStudy.ZKConnect.main(ZKConnect.java:26)] - [WARN] 连接状态:CONNECTED

Process finished with exit code 0

会话恢复

public class ZKConnectSessionWatch implements Watcher {

    private final static Logger log = LoggerFactory.getLogger(ZKConnectSessionWatch.class);
    private static final String zkServerPath = "192.168.1.53:2181";
    private static final Integer timeout = 5000;

    public static void main(String[] args) throws IOException, InterruptedException {
        ZooKeeper zooKeeper = new ZooKeeper(zkServerPath,timeout,new ZKConnectSessionWatch());
        long sessionId = zooKeeper.getSessionId();
        String ssid = "0x" + Long.toHexString(sessionId);
        System.out.println(ssid);
        byte[] sessionPasswd = zooKeeper.getSessionPasswd();

        log.warn("客户端开始连接zookeeper服务器...");
        log.warn("连接状态:{}", zooKeeper.getState());
        new Thread().sleep(2000);
        log.warn("连接状态:{}", zooKeeper.getState());
        new Thread().sleep(200);

        log.warn("开始会话重连");
        ZooKeeper zooKeeperSession = new ZooKeeper(zkServerPath,
                timeout,
                new ZKConnectSessionWatch(),
                sessionId,
                sessionPasswd);
        log.warn("重新连接状态zkSession:{}", zooKeeperSession.getState());
        new Thread().sleep(1000);
        log.warn("重新连接状态zkSession:{}", zooKeeperSession.getState());


    }

    public void process(WatchedEvent watchedEvent) {
        log.warn("接受到watch通知:{}", watchedEvent);
    }
}

控制台输出

0x0
2018-04-20 14:02:45,702 [main] [com.zj.zookeeperStudy.ZKConnectSessionWatch.main(ZKConnectSessionWatch.java:24)] - [WARN] 客户端开始连接zookeeper服务器...
2018-04-20 14:02:45,708 [main] [com.zj.zookeeperStudy.ZKConnectSessionWatch.main(ZKConnectSessionWatch.java:25)] - [WARN] 连接状态:CONNECTING
2018-04-20 14:02:45,776 [main-EventThread] [com.zj.zookeeperStudy.ZKConnectSessionWatch.process(ZKConnectSessionWatch.java:44)] - [WARN] 接受到watch通知:WatchedEvent state:SyncConnected type:None path:null
2018-04-20 14:02:47,709 [main] [com.zj.zookeeperStudy.ZKConnectSessionWatch.main(ZKConnectSessionWatch.java:27)] - [WARN] 连接状态:CONNECTED
2018-04-20 14:02:47,909 [main] [com.zj.zookeeperStudy.ZKConnectSessionWatch.main(ZKConnectSessionWatch.java:30)] - [WARN] 开始会话重连
2018-04-20 14:02:47,911 [main] [com.zj.zookeeperStudy.ZKConnectSessionWatch.main(ZKConnectSessionWatch.java:36)] - [WARN] 重新连接状态zkSession:CONNECTING
2018-04-20 14:02:47,928 [main-EventThread] [com.zj.zookeeperStudy.ZKConnectSessionWatch.process(ZKConnectSessionWatch.java:44)] - [WARN] 接受到watch通知:WatchedEvent state:SyncConnected type:None path:null
2018-04-20 14:02:48,912 [main] [com.zj.zookeeperStudy.ZKConnectSessionWatch.main(ZKConnectSessionWatch.java:38)] - [WARN] 重新连接状态zkSession:CONNECTED

Process finished with exit code 0

节点的增删改查

创建节点

创建节点有同步和异步两种方式

public void createZKNode(String path, byte[] data, List<ACL> acls) {

        String result = "";
        try {
            /**
             * 同步或者异步创建节点,都不支持子节点的递归创建,异步有一个callback函数
             * 参数:
             * path:创建的路径
             * data:存储的数据的byte[]
             * acl:控制权限策略
             * 			Ids.OPEN_ACL_UNSAFE --> world:anyone:cdrwa
             * 			CREATOR_ALL_ACL --> auth:user:password:cdrwa
             * createMode:节点类型, 是一个枚举
             * 			PERSISTENT:持久节点
             * 			PERSISTENT_SEQUENTIAL:持久顺序节点
             * 			EPHEMERAL:临时节点
             * 			EPHEMERAL_SEQUENTIAL:临时顺序节点
             */
            //同步
//            result = zooKeeper.create(path, data, acls, CreateMode.PERSISTENT);

            //异步
			String ctx = "{'create':'success'}";
			zooKeeper.create(path, data, acls, CreateMode.PERSISTENT, new CreateCallBack(), ctx);

            System.out.println("创建节点:\t" + result + "\t成功...");
            new Thread().sleep(2000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args){
        ZKNodeOperator zkNodeOperator = new ZKNodeOperator(zkServerPath);

        zkNodeOperator.createZKNode("/test1","test1".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE);
    }

其中CreateCallBack代码如下

public class CreateCallBack implements StringCallback {

	public void processResult(int rc, String path, Object ctx, String name) {
		System.out.println("创建节点: " + path);
		System.out.println((String)ctx);
	}

}

删除节点

删除节点也有两种方式,同步和异步两种方式

    public static void main(String[] args) throws KeeperException, InterruptedException {
        ZKNodeOperator zkNodeOperator = new ZKNodeOperator(zkServerPath);

        zkNodeOperator.createZKNode("/test1delete","test1delete".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE);
        //同步
//        zkNodeOperator.getZooKeeper().delete("/test1delete", 0);
// 异步
        String ctx = "{'delete':'success'}";
        zkNodeOperator.getZooKeeper().delete("/test1delete", 0, new DeleteCallBack(), ctx);
        Thread.sleep(2000);
    }

其中DeleteCallBack代码如下

public class DeleteCallBack implements VoidCallback {
	public void processResult(int rc, String path, Object ctx) {
		System.out.println("删除节点" + path);
		System.out.println((String)ctx);
	}

}

修改节点数据

修改节点数据也有同步和异步两种方式

public static void main(String[] args) throws KeeperException, InterruptedException {
        ZKNodeOperator zkNodeOperator = new ZKNodeOperator(zkServerPath);
        //zkNodeOperator.createZKNode("/testset", "testset".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE);
        //同步修改数据
//        Stat stat = zkNodeOperator.getZooKeeper().setData("/testset", "xyz".getBytes(), 0);
//        System.out.println(stat.getVersion());
        //异步修改数据
        String ctx = "{'set':'success'}";
        zkNodeOperator.getZooKeeper().setData("/testset", "abcddd".getBytes(),2, new DateSetCallBack(),ctx);
        new Thread().sleep(2000);
    }

其中DateSetCallBack代码如下

public class DateSetCallBack implements StatCallback {
    public void processResult(int rc, String path, Object ctx, Stat stat) {
        System.out.println("修改节点:" + path);
        System.out.println((String)ctx);
        System.out.println(stat.getVersion());
    }
}

节点数据查询

节点数据查询有三种方式

获取节点数据
获取子节点数据
判断节点是否存在

watch与acl的相关操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值