本文重点在分析zk watcher实现机制!!!
从zkCli.sh可以看出启动类是ZooKeeperMain,一打开此类就能看到zk支持的指令列表。

main方法主要流程:参数解析,维护已发送指令历史。构造ZooKeeper对象,启动发送线程和事件处理线程。主线程用于接收指令。
ZooKeeper最重要的状态是ZKWatchManager对象,ZKWatchManager里面有三个map,节点绝对路径以及对应的watcher集合:
Map<String, Set<Watcher>> dataWatches:监控节点数据变化。
Map<String, Set<Watcher>> existWatches:监控节点存在性变化。
Map<String, Set<Watcher>> childWatches:监控子节点变化。
是不是很神奇。我之前一直以为watcher会序列化之后发送zk server。其实watcher是保存在client端的。
ZKWatchManager构造时会同时构造出ClientCnxn对象,ClientCnxn构造时默认使用ClientCnxnSocketNIO类处理IO。
ClientCnxn最重要的两个状态:
LinkedList<Packet> pendingQueue:已经发送等待响应的请求。
LinkedList<Packet> outgoingQueue:待发送队列。
ClientCnxn构造时会同时构造出两个线程:
SendThread:用于发送请求。
线程启动时,注册socket到selector,然后等待连接完成和read/write就绪。

连接完成之后,调用primeConnection,如果支持autoWatchReset,把当前的watcher重新set一遍。只监听读写事件,不再监听connect事件。

write事件发生时,从请求队列里取一个发送给server,然后加入等待响应队列。



根据响应的结果以及watcher的类型,注册watcher到ZKWatchManager。通知发送请求的client,请求处理完成。

收到通知,加入EventThread的通知队列。如果是watcher事件,同时找到注册的监听此路径此事件的所有watcher。
EventThread:用于处理通知。主要状态是LinkedBlockingQueue<Object> waitingEvents保存收到的通知。


event一共分两种:watcher事件和callback,收到通知事件时执行watcher和callback。
以get data为例说明zk server对watcher的处理:
GetDataRequest只有两个属性:String path和boolean watch。
FinalRequestProcessor处理get data请求时,如果watch=true,就传递NIOServerCnxn给data tree。NIOServerCnxn本身实现了Watched接口,在需要触发watcher时,把WatchedEvent返回给client。

data tree遇到watcher,记录下来哪个client在监控哪个路径

data tree处理set data指令时:



create:触发节点的NodeCreated事件和父节点的NodeChildrenChanged事件。
delete:触发节点的NodeDeleted事件和父节点的NodeChildrenChanged事件。
setdata:触发节点的NodeDataChanged事件。
setacl:不触发事件。
本节完。。。。