手搓zookeeper样例实现记录

在学习zookeeper过程中,学习了一个监听节点状态变化,而开始、停止计数的案例。看懂了不代表就会了,于是想自己实现一个简单的版本。在自己实现的过程中也遇到了一些问题,在这里记录一下。

实现代码内容

  • 在zookeeper中创建/YuYang节点开始计数

  • 在zookeeper中删除/YuYang节点停止计数

遇到问题:

1、zookeeper收不到节点的创建与删除事件,代码如下

public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
    ZookeeperDemo demo = new ZookeeperDemo();
    zooKeeper = new ZooKeeper(ZK_HOST, 600, demo);
    latch.await();
}

@Override
public void process(WatchedEvent watchedEvent) {
    if (watchedEvent.getType() == Event.EventType.None) {

    } else {
        System.out.println(watchedEvent.getPath());
        if (!watchedEvent.getPath().isEmpty() && watchedEvent.getPath().equals(WATCH_PATH)) {
            zooKeeper.exists(WATCH_PATH, this, this, null);
        }
    }
}

通过打断点,发现process函数处理的事件类型都是None。并没有收到节点创建和删除的事件。

通过和官方示例对比,发现少了一行,在ZooKeeper创建后,先调用一次exists的方法。

public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
    ZookeeperDemo demo = new ZookeeperDemo();
    zooKeeper = new ZooKeeper(ZK_HOST, 60000, demo);
    zooKeeper.exists(WATCH_PATH, true, demo, null);
    latch.await();
}

ToDo: 通过源码分析原因

加上之后,便能收到节点的创建事件,但是节点的删除事件始终收不到。

2、zookeeper收不到节点删除事件

在收到节点创建事件后,开启线程执行计数线程。但是收不到删除事件,导致计数无法停止,代码如下:

@Override
public void processResult(int rc, String path, Object ctx, Stat stat) {
    System.out.println(stat);
    if (stat == null) {
        if (flag) {
            System.out.println("latch.countDown");
            latch.countDown();
        }
    } else {
        runnable.run();
    }
}

通过日志能看到,节点是删除的。但是为什么没有调用我的回调函数呢?

在这里插入图片描述

最后发现,我的开启新线程的方式,仅仅是runnable.run(),并没有新起线程,最终导致把线程卡死住了:

private final Runnable runnable = () -> {
    int i = 0;
    flag = true;
    while (true) {
        System.out.println(i++);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
};

修复,最后程序就如愿跑起来了:

new Thread(runnable).start();

ToDo: 从源码看看,zookeeper客户端的线程设计。

3、打断点时间太长,程序自动退出

在这里插入图片描述

是由于初始化参数导致:

zooKeeper = new ZooKeeper(ZK_HOST, 6000, demo);

通过注释知道,是和zookeeper服务器保持发送心跳的超时时间,单位为毫秒。设置为6000时,即为6s,所以打断点时间过长,连接就断了。

在这里插入图片描述

全量代码:https://github.com/CNYuYang/study/blob/master/zookeeper/src/main/java/run/yuyuang/zk/ZookeeperDemo.java

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值