在前面说的原来的zk的java api中,提供了watcher的机智监听节点,zkclient将之转换成Listener的概念,就是订阅服务端的事件。
下面一个小程序,简单验证一下节点的监听
日志输出: 一目了然
来看看注册的监听,IZkChildListener,这个接口一个方法handleChildChange,两个参数
parentPath:节点变动的通知父节点路径
currentChilds:子节点路径们
其实一个节点不存在也是可以先设置监听的,只是这边zk-xin已经存在了,所以没写而已
而且这边订阅后,不用反复注册(不像api自带的那种,因为watcher是一次性的)
另一个订阅监听事件是节点数据变更,实现下面两个方法就行啦,数据变化包含数据内容和版本概念
还有一个关于连接的监听,可以监听连接状态的变化,还有session是否改变,这样做的目的可能是为了注册临时节点吧,就像dubbo服务的注册。
zkclient的打包的结构:
exception:放的都是异常类
serialize:放的是序列化实现,这边有两个实现ZkSerializer接口的类,默认是SerializableSerializer,另一个是BytesPushThroughSerializer相当于什么都没干,byte[]与object的互换而已。
另外一些是具体要参与工作的类
下面来看看订阅事件的实现,这边用了同步锁,这样的话不能同时注册多个吗?当然对zklient是没影响,因为与数据监听和状态监听使用不同的同步对象控制,不同的zklient实现,当然就更没影响啦。
这边主要执行了watchForChilds方法,这边启动一个线程,线程内先执行exists方法,后执行获取子节点的操作,其他的也是类似
既然注册了时间,总要有人去做这件事情吧,可以看到ZkClient 实现了接口org.apache.zookeeper.Watcher,watcher有个抽象方法abstract public void process(WatchedEvent event);
下面是zkclient的实现,先判断事件的类型,然后执行不同的操作,比如上面的子节点监听,和执行processDataOrChildChange(event);
子节点的变更后面执行的是ireChildChangedEvents(path, childListeners);
最后干苦力的是ZkEvent方法,这边执行了一下List<String> children = getChildren(path);重新获取了节点数据
还有就是不监听啦,就是吧对应的listener移除
祝大家周末愉快,我要加班 加班啊