前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Watcher---Zk事件监听机制和原理

Watcher---Zk事件监听机制和原理

作者头像
名字是乱打的
发布2021-12-22 16:18:50
1.3K0
发布2021-12-22 16:18:50
举报
文章被收录于专栏:软件工程软件工程

Zookeeper的Watcher 监听机制是 Zookeeper 中非常重要的特性,很多时候我们之所以用Zookeeper的原因其实都是因为Zookeeper这个特性.

想一想,我其实很久之前貌似做过类似于持续集成自动配置方面的尝试,那时候好像用的是MQ,我的配置改变了后向MQ发个消息,然后客户端的MQ消费者重新拉配置下来进行更新...

一. Zookeeper事件监听机制

我们基于 zookeeper 上创建的节点,可以对这些节点绑定监听事件,比如可以监听节点数据变更、节点删除、子节点状态变更等事件,通过这个事件机制,可以基于 zookeeper实现分布式锁集群管理等功能

watcher 特性当数据发生变化的时候, zookeeper 会产生一个

watcher 事件,并且会发送到客户端。但是客户端只会收到一次

通知。如果后续这个节点再次发生变化,那么之前设置 watcher 的客户端不会再次收到消息。(watcher 是一次性的操作)。

可以通过循环监听去达到永久监听效果.

二 .如何绑定事件机制呢?

以下三个方法均可在使用时候绑定事件.

  • getData
  • Exists
  • getChildren
那么哪些操作会触发事件呢?

如何触发事件? 凡是事务类型的操作,都会触发监听事件。 其实也就是create /delete /setData

三 watcher 事件类型
  • None (-1), 客户端链接状态发生变化的时候,会收到 none 的事件
  • NodeCreated (1), 创建节点的事件。
  • NodeDeleted (2), 删除节点的事件
  • NodeDataChanged (3), 节点数据发生变更
  • NodeChildrenChanged (4); 子节点被创建、被删除、会发生事件触发

举个栗子

代码语言:javascript
复制
private static void addEvent(String path) throws KeeperException, InterruptedException {
        zooKeeper.exists(path, new Watcher(){
            @Override
            public void process(WatchedEvent watchedEvent) {
                System.out.println("触发事件机制的路径为:"+watchedEvent.getPath());
                System.out.println("事件类型为:"+watchedEvent.getType());
            }
        });
    }

结果如下图,这也体现了事件的一次性性质,我们明明改变了两次却只触发了一次.

根据人家ZK文档,这里我们加入循环试试,我在添加事件机制在结束的时候,我又再次的为/test结点添加了事件

代码语言:javascript
复制
   private static void addEvent(String path) throws KeeperException, InterruptedException {
        zooKeeper.exists(path, new Watcher(){
            @Override
            public void process(WatchedEvent watchedEvent) {
                System.out.println("触发事件机制的路径为:"+watchedEvent.getPath());
                System.out.println("事件类型为:"+watchedEvent.getType());
                //再次为该结点绑定监听,使监听机制有效
                try {
                    zooKeeper.exists(watchedEvent.getPath(),true);
                } catch (KeeperException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }

但是结果如下,我们还是没有监听到事件

那么问题出在哪里呢?实际上,我们在zooKeeper.exists(watchedEvent.getPath(),true);开启的不是exits里自添加的事件,而是走的默认全局事件,我们在创建结点时候添加了一个事件

这里我们验证一下,添加一个全局事件打印

结果如下,验证了我们的猜想

各种操作对应的事件类型

二 . Zookeeper的实现原理

关于watcher事件监听机制,客户端与服务器的大致协调.服务器会受到客户端的命令,使服务器知道哪些Znode开启了事件

watcher源码流程:

源码大致流程

具体源码分析:

首先找到我们添加事件监听机制的方法,比如exists

唤醒触发机制

上面的源码分析我们发现我们只是添加了监听事件的入队,那么出队的消费呢?在哪?

回头我们看一下Zookeeper的构造方法

发现里面启动了俩线程

还有一些判断比如to判断心跳问题

很多很多的判断之后发现最后发现一切正常后,调用传输socket

不论是我们用NIO还是Netty,其消费都是差不多的.我们以Netty为例看下源码.

DoWrite 方法

sendPkt

到此ZK监听机制的客户端部分分析完成!

关于ZK服务器端的watcher机制分析.

跟着某大佬提供的服务端接收请求处理流程总流程,我们看看源码

服务端接收请求处理流程

以后再分析服务端,现在写论文去了.....

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/10/26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一. Zookeeper事件监听机制
  • 二 .如何绑定事件机制呢?
  • 三 watcher 事件类型
  • 举个栗子
  • 各种操作对应的事件类型
    • 二 . Zookeeper的实现原理
      • watcher源码流程:
        • 具体源码分析:
          • 关于ZK服务器端的watcher机制分析.
            • 服务端接收请求处理流程
            相关产品与服务
            持续集成
            CODING 持续集成(CODING Continuous Integration,CODING-CI)全面兼容 Jenkins 的持续集成服务,支持 Java、Python、NodeJS 等所有主流语言,并且支持 Docker 镜像的构建。图形化编排,高配集群多 Job 并行构建全面提速您的构建任务。支持主流的 Git 代码仓库,包括 CODING 代码托管、GitHub、GitLab 等。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档