在客户端发送命令:stat /zhang watch

在zk server中产生如下图的调用栈:

  1. //在DataTree类中有
  2. private final WatchManager dataWatches = new WatchManager();
  3.  
  4. //在WatchManager类中有
  5. private final HashMap<String, HashSet<Watcher>> watchTable =
  6. new HashMap<String, HashSet<Watcher>>();
  7.  
  8. private final HashMap<Watcher, HashSet<String>> watch2Paths =
  9. new HashMap<Watcher, HashSet<String>>();

我们详细分析addWatch代码:

  1. //path就是客户端命令中的"/zhang",而Watcher就是客户端的连接对象NIOServerCnxn
  2. //可以理解为客户端就是一个Watcher
  3. //public abstract class ServerCnxn implements Stats, Watcher
  4. //public class NIOServerCnxn extends ServerCnxn
  5. public synchronized void addWatch(String path, Watcher watcher) {
  6. //多个客户端关注一个path
  7. HashSet<Watcher> list = watchTable.get(path);
  8. if (list == null) {
  9. // don't waste memory if there are few watches on a node
  10. // rehash when the 4th entry is added, doubling size thereafter
  11. // seems like a good compromise
  12. list = new HashSet<Watcher>(4);
  13. watchTable.put(path, list);
  14. }
  15. list.add(watcher);
  16.  
  17. //一个客户端关注多个path
  18. HashSet<String> paths = watch2Paths.get(watcher);
  19. if (paths == null) {
  20. // cnxns typically have many watches, so use default cap here
  21. paths = new HashSet<String>();
  22. watch2Paths.put(watcher, paths);
  23. }
  24. paths.add(path);
  25. }

在创建、删除、设置节点数据时,会触发watch:

  1. public Set<Watcher> triggerWatch(String path, EventType type, Set<Watcher> supress) {
  2. //生成事件
  3. WatchedEvent e = new WatchedEvent(type, KeeperState.SyncConnected, path);
  4. HashSet<Watcher> watchers;
  5. synchronized (this) {
  6. //删除关注path的客户端
  7. watchers = watchTable.remove(path);
  8. if (watchers == null || watchers.isEmpty()) {
  9. if (LOG.isTraceEnabled()) {
  10. ZooTrace.logTraceMessage(LOG,
  11. ZooTrace.EVENT_DELIVERY_TRACE_MASK,
  12. "No watchers for " + path);
  13. }
  14. return null;
  15. }
  16. for (Watcher w : watchers) {
  17. //删除该客户端关注的path
  18. HashSet<String> paths = watch2Paths.get(w);
  19. if (paths != null) {
  20. paths.remove(path);
  21. }
  22. }
  23. }
  24. for (Watcher w : watchers) {
  25. if (supress != null && supress.contains(w)) {
  26. continue;
  27. }
  28. //每个客户端处理watch事件
  29. //NIOServerCnxn.process(WatchedEvent event)
  30. w.process(e);
  31. }
  32. return watchers;
  33. }

zk如何实现watch的更多相关文章

  1. zk 起别名时候碰到的问题

    第一次搭建时候都是用的ip,没什么问题,看到别人都是用的别名,于是也想试试把ip改成别名.然而 其中碰到的问题 ,快一周了才解决,现在记录下: 1.改主机别名 一直以为 修改 /etc/hosts 里 ...

  2. 基于ZK构建统一配置中心的方案和实践

    背景: 近期使用Zk实现了一个简单的配置管理的小东西,在此开源出来,有兴趣的希望提出您的宝贵意见.如果恰巧您也使用或者接触过类似的东西, 也希望您可以分享下您觉得现在这个项目可以优化和改进的地方. 项 ...

  3. ZK 使用jfreeChart

    前台: <?page title="Grid使用" contentType="text/html;charset=UTF-8"?> <zk x ...

  4. dubbo zk 分布式服务项目搭建与配置

    1. 项目 jar  -----提供接口 2. 项目 jar  -----接口实现   provider启动zk main方法启动 start applicationContext.xml <b ...

  5. ZK 最少限度加载页面js文件

    官方文档说明: ZK Developer's Reference文档,章节为Minimize Number of JavaScript Files to Load,按照文档步骤执行,最后需在 web. ...

  6. ZK textbox Constraint验证

    test.zul: <?page title="" contentType="text/html;charset=UTF-8"?> <zk x ...

  7. ZK listbox 两种分页使用及比较

    参考:http://tsinglongwu.iteye.com/blog/849923 以下代码模拟数据量大时情况,采用“<paging>”组件方式 前台Listbox.zul : < ...

  8. disconf系列【2】——解决zk部署情况为空的问题

    如下图所示,在安装完成之后,发现zk(zookeeper)部署情况为空. 注:承接上篇,环境未发生改变. 1.解决zk没有启动的问题 查看disconf日志,发现zk没有启动. 实际情况是:zk已经启 ...

  9. zk系列-zookeeper的使用

    zk支持java/c访问,java常用的有apache-zkclient.社区版的i0tec-zkclient.github.adyliu,apache-zkclient是zk自身提供的接口,i0te ...

  10. zk系列-zookeeper概述

    接触zk是2年前了,最近工作又比较依赖于zk,所以准备起个系列文章,系统的总结下. zookeeper是一个分布式的用于协调的服务,起源于Hadoop中的一个组件.分布式系统可以用zookeeper实 ...

随机推荐

  1. P4878 [USACO05DEC]layout布局

    P4878 [USACO05DEC]layout布局 差分约束 最短路径最长路,最长路径最短路 本题求的是最长路径,所以跑最短路 根据题意连边,然后spfa即可 注意要判断图的连通性,所以新建一个虚拟 ...

  2. 20145122 《Java程序设计》第8周学习总结

    教材学习内容总结 1.NIO使用频道(channel)来衔接数据节点,对数据区的标记提供了clear(),rewind(),flip(),compact()等高级操作. 2.想要取得channel的操 ...

  3. Spark On YARN 分布式集群安装

    一.导读 最近开始学习大数据分析,说到大数据分析,就必须提到Hadoop与Spark.要研究大数据分析,就必须安装这两个软件,特此记录一下安装过程.Hadoop使用V2版本,Hadoop有单机.伪分布 ...

  4. Log4j将不同Package的日志输出到不同的文件的方法

    随着项目规模的越来越大,会不断的引入新的模块,不同的模块都会打印自己的日志,最后就造成日志根本没法查看,比如我自己的项目中,就存在以下这些日志: 接收外界消息的日志.对外发送消息的日志: 后台常驻线程 ...

  5. C# 图片和64位编码的转换

    /* 将图片转换为64位编码 */ //找到文件夹 System.IO.DirectoryInfo dd = new System.IO.DirectoryInfo("C://qq" ...

  6. AndroidStudio V2.0.0.汉化

    汉化包下载:http://pan.baidu.com/s/1kVKYUjH AndroidStudio V2.0.x.版汉化工作介绍 resource_en.jar------> resourc ...

  7. JavaScript:Object属性方法

    Object的属性(firebug中没有找到) var pro={ city:"shanghai", list:[,,,,] } var Person=function(name, ...

  8. Spring Boot条件注解

    一.为什么SpringBoot产生于Spring4? Spring4中增加了@Condition annotation, 使用该Annotation之后,在做依赖注入的时候,会检测是否满足某个条件来决 ...

  9. 【maven】在IDEA上 使用maven进行打包时报错:Failed to execute goal org.apache.maven.plugins:maven-javadoc-plugin:2.10.3:jar

    报错内容如下: [INFO] ------------------------------------------------------------------------ [INFO] BUILD ...

  10. gulp报错插件gulp-notify 配置项

    var notify = require("gulp-notify"); module.exports = function(){ var args = Array.prototy ...