ZK java操作 详解

4 篇文章 0 订阅
3 篇文章 0 订阅

它是一个为分布式应用提供一致性服务的软件。
Zookeeper 作为一个分布式的服务框架,主要用来解决分布式集群中应用系统的一致性问题,它能提供基于类似于文件系统的目录节点树方式的数据存储, Zookeeper 作用主要是用来维护和监控存储的数据的状态变化,通过监控这些数据状态的变化,从而达到基于数据的集群管理。

java 操作

//创建zk连接
ZooKeeper zk = new ZooKeeper(CONNETTION_ADDR, SESSION_TIMEOUT, new Watcher() {
            public void process(WatchedEvent event) {
                // 获取时间的状态
                //通知状态
                KeeperState keeperState = event.getState();
                //事件类型
                EventType tventType = event.getType();
                // 如果是建立连接
                if (KeeperState.SyncConnected == keeperState) {
                    if (EventType.None == tventType) {
                        System.out.println("创建zk连接");
                    }
                }
            }
        });
        //创建zk节点
        zk.create("/zk", "testZookeeper".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

		//使用zkclient包的方式
        ZkClient zkClient=new ZkClient("host");
        zkClient.createEphemeral("path");

监听

package com.zk.watcher;

import java.util.concurrent.CountDownLatch;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;

public class ZookeeperWatcher implements Watcher {
    // 集群连接地址
    private static final String CONNECT_ADDRES = "127.0.0.1:2181";
    // 会话超时时间
    private static final int SESSIONTIME = 2000;
    // 信号量,zk连接异步,用于阻塞,保证所有的操作都在zk创建连接成功以后再执行
    private static final CountDownLatch countDownLatch = new CountDownLatch(1);
    private ZooKeeper zk;

    public void createConnection(String connectAddres, int sessionTimeOut) {
        try {
            zk = new ZooKeeper(connectAddres, sessionTimeOut, this);
            System.out.println("LOG" + "zk 开始启动连接服务器....");
            countDownLatch.await();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public boolean createPath(String path, String data) {
        try {
            this.exists(path, true);
            // 创建持久节点
            this.zk.create(path, data.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            System.out.println("LOG" + "节点创建成功, Path:" + path + ",data:" + data);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

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

    public boolean updateNode(String path, String data) throws KeeperException, InterruptedException {
        exists(path, true);
        this.zk.setData(path, data.getBytes(), -1);
        return false;
    }

    public void process(WatchedEvent watchedEvent) {

        // 获取事件状态
        KeeperState keeperState = watchedEvent.getState();
        // 获取事件类型
        EventType eventType = watchedEvent.getType();
        // zk 路径
        String path = watchedEvent.getPath();
        // 判断是否建立连接
        if (KeeperState.SyncConnected == keeperState) {
            // 如果当前状态已经连接上了 SyncConnected:连接,AuthFailed:认证失败,Expired:失效过期,
            // ConnectedReadOnly:连接只读,Disconnected:连接失败
            if (EventType.None == eventType) {
                // 如果建立建立成功,让后程序往下走
                System.out.println("LOG" + "zk 建立连接成功!");
                countDownLatch.countDown();
            } else if (EventType.NodeCreated == eventType) {
                System.out.println("LOG" + "事件通知,新增node节点" + path);
            } else if (EventType.NodeDataChanged == eventType) {
                System.out.println("LOG" + "事件通知,当前node节点" + path + "被修改....");
            } else if (EventType.NodeDeleted == eventType) {
                System.out.println("LOG" + "事件通知,当前node节点" + path + "被删除....");
            }

        }
    }

    public static void main(String[] args) throws KeeperException, InterruptedException {
        ZookeeperWatcher zkClientWatcher = new ZookeeperWatcher();
        zkClientWatcher.createConnection(CONNECT_ADDRES, SESSIONTIME);
        zkClientWatcher.createPath("/createNode", "pa-644064");
        // 修改createNode节点
        zkClientWatcher.updateNode("/createNode", "7894561");
    }

}

节点注册和监听

package com.zk.distributed;

import java.util.concurrent.CountDownLatch;

import org.I0Itec.zkclient.IZkDataListener;

public class ZkDistributeLock extends ZkDistributedAbstractLock {

    @Override
    Boolean tryGetLock() {
        try {
            zkClient.createEphemeral(PATH);
            return true;
        } catch (Exception e) {
            return false;
        }

    }

    @Override
    void waitUnLock() {

        // 使用事件监听,获取到节点被删除,zookeeper上节点有什么变化都可以感知到
        IZkDataListener iZkDataListener = new IZkDataListener() {
            // 当节点被删除
            public void handleDataDeleted(String dataPath) throws Exception {
                if (countDownLatch != null) {
                    // 唤醒
                    countDownLatch.countDown();
                }

            }

            // 当节点发生改变
            public void handleDataChange(String dataPath, Object data) throws Exception {

            }
            
        };

        // 注册节点信息
        zkClient.subscribeDataChanges(PATH, iZkDataListener);
        //检测是否存在该节点信息
        if (zkClient.exists(PATH)) {
            // 创建信号量
            countDownLatch = new CountDownLatch(1);
            try {
                // 等待
                countDownLatch.await();
            } catch (Exception e) {

            }

        }
        // 删除事件通知
        zkClient.unsubscribeDataChanges(PATH, iZkDataListener);
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值