zookeeper(二) 数据发布与订阅(配置中心)

首先需要引用 zookeeper

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

1 ZkServicce zk服务类

public class ZkServicce {
    private static ZooKeeper zk;
    private static final int SESSION_TIMEOUT = 30 * 1000;
    public static String ZOOKEEPER_PATH = "/zookeeper";

    static {

        try {
            //创建zk连接
            createZk();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            //创建path
            createZkPath();
        } catch (KeeperException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    public static void createZk() throws IOException {
        if (zk == null)
            zk = new ZooKeeper("localhost:2181,localhost:2182,localhost:2183", SESSION_TIMEOUT, null);
    }

    public static void createZkPath() throws KeeperException, InterruptedException {
        Stat stat = null;
        stat = zk.exists(ZOOKEEPER_PATH, false);
        if (stat == null)
            zk.create(ZkServicce.ZOOKEEPER_PATH, ("hello word").getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
    }

    public static ZooKeeper getZk() {
        return zk;
    }

    public static void setZk(ZooKeeper zk) {
        ZkServicce.zk = zk;
    }

}

2 Provider 生产者

public class Provider {

    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
        int i = 0;
        // 每秒执行一次
        while (true) {
            i++;
            //不区分版本 version=-1
            ZkServicce.getZk().setData(ZkServicce.ZOOKEEPER_PATH, ("hello word" + i).getBytes(), -1);
            Thread.sleep(1000);
        }

    }

}

3 Customer

public class Customer {
    private Watcher wh = new Watcher() {
        /**
         * Watched事件
         */
        public void process(WatchedEvent event) {
            System.out.println("返回事件:" + event.toString());

            if (event.getPath() != null)
                try {
                    System.out
                            .println("监听事件中的值:" + new String(ZkServicce.getZk().getData(event.getPath(), false, null)));
                } catch (KeeperException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

        }
    };

    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
        Customer customer = new Customer();
        while (true) {
            System.out.println(
                    "获取值:" + new String(ZkServicce.getZk().getData(ZkServicce.ZOOKEEPER_PATH, customer.wh, null)));// 添加Watch
            Thread.sleep(1000);

        }

    }
}

这里写图片描述

每秒修改一次数据,每秒接受一次数据并且对path进行监听,当且仅有一次数据修改时,调用监听事件。
由于 监听事件只能被调用一次的特性,所以每次都得设置监听,也挺烦的。
所以 我们使用 ZkClient 封装了zk,让我们很方便的使用zk。

1 ZkClientServicce

public class ZkClientServicce {
    private static ZkClient zkClient;
    private static final int SESSION_TIMEOUT = 30 * 1000;
    public static String ZOOKEEPER_PATH = "/zookeeper";

    static {

        try {
            // 创建zk连接
            createZk();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            // 创建path
            createZkPath();
        } catch (KeeperException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    public static void createZk() throws IOException {
        if (zkClient == null)
            zkClient = new ZkClient("localhost:2181,localhost:2182,localhost:2183", SESSION_TIMEOUT, SESSION_TIMEOUT);

    }

    public static void createZkPath() throws KeeperException, InterruptedException {

        boolean exist = zkClient.exists(ZOOKEEPER_PATH);
        if (!exist)
            zkClient.createPersistent(ZkClientServicce.ZOOKEEPER_PATH, ("hello word").getBytes());
    }

    public static ZkClient getZkClient() {
        return zkClient;
    }

    public static void setZkClient(ZkClient zkClient) {
        ZkClientServicce.zkClient = zkClient;
    }

}

2 ZkClientProvider

public class ZkClientProvider {

public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
    int i = 0;
    // 每秒执行一次
    while (true) {
        i++;
        // 不区分版本 version=-1
        ZkClientServicce.getZkClient().writeData(ZkServicce.ZOOKEEPER_PATH, "hello word" + i);
        Thread.sleep(1000);
    }

}

}
3 ZkClientCustomer

public class ZkClientCustomer {
    private static class ZKDataListener implements IZkDataListener {

        /**
         * @Title: handleDataChange
         * @Description:修改节点
         * @author xier
         * @param @param
         *            dataPath
         * @param @param
         *            data
         * @param @throws
         *            Exception
         */
        public void handleDataChange(String dataPath, Object data) throws Exception {

            System.out.println("节点修改事件:" + dataPath + ":" + data.toString());
        }

        /**
         * @Title: handleDataDeleted
         * @Description:删除节点
         * @author xier
         * @param @param
         *            dataPath
         * @param @throws
         *            Exception
         */
        public void handleDataDeleted(String dataPath) throws Exception {
            System.out.println("节点删除事件:" + dataPath);
        }

    }

    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
        ZkClientServicce.getZkClient().subscribeDataChanges(ZkClientServicce.ZOOKEEPER_PATH, new ZKDataListener());
        Thread.sleep(Integer.MAX_VALUE);
    }
}

这里写图片描述
是不是方便了很多呢,减少了很多判断,也不需要每次都需要通过 read,state,child 绑定监听。
好了,数据发布与订阅的简单例子就到这里!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值