zookeeper配置管理实现原理----监听事件watch
Watch监听概述
•ZooKeeper 允许用户在指定节点上注册一些Watcher,并且在一些特定事件触发的时候,ZooKeeper 服务端会将事件通知到感兴趣的客户端上去,该机制是 ZooKeeper 实现分布式协调服务的重要特性。
•ZooKeeper 中引入了Watcher机制来实现了发布/订阅功能能,能够让多个订阅者同时监听某一个对象,当一个对象自身状态变化时,会通知所有订阅者。
•ZooKeeper 原生支持通过注册Watcher来进行事件监听,但是其使用并不是特别方便,需要开发人员自己反复注册Watcher,比较繁琐。
•Curator引入了 Cache 来实现对 ZooKeeper 服务端事件的监听。
•ZooKeeper提供了三种Watcher:
- NodeCache : 只监听某一个特定的节点
- PathChildrenCache : 监控一个ZNode的子节点
- TreeCache : 可以监控整个树上的所有节点,类似于PathChildrenCache和NodeCache的组合
在获得客户端对象和关闭客户端对象都做好准备之后:
@Test//测试监听单个结点 public void testListenOneNode() throws Exception { NodeCache nodeCache = new NodeCache(client, "/app2");//创建NodeCache对象 nodeCache.getListenable().addListener(new NodeCacheListener() { @Override public void nodeChanged() throws Exception { System.out.println("结点发生变化了!"); } }); nodeCache.start(true);//开启监听,如果参数是true则在监听时加载缓存数据 while (true) { //一直监听 } }
@Test//监听指定结点的所有子节点 public void testPathNodeCache() throws Exception { //1.创建子节点监听对象 PathChildrenCache pathChildrenCache = new PathChildrenCache(client, "/app1", true); //2.怎么进行监听? pathChildrenCache.getListenable().addListener(new PathChildrenCacheListener() { @Override public void childEvent(CuratorFramework curatorFramework, PathChildrenCacheEvent pathChildrenCacheEvent) throws Exception { System.out.println("app1的子节点发生变化了!"); System.out.println(pathChildrenCacheEvent); } }); //3.开启监听 pathChildrenCache.start(); while (true) { } } =========================================================================================================== @Test//获得监听的类型和监听的内容 public void testgetPathtype() throws Exception { //1.创造监听器 final PathChildrenCache pathChildrenCache = new PathChildrenCache(client, "/app2", false);//cache缓存如果设置为false的话是不能获得及时变化的数据的 //2怎么进行监听? pathChildrenCache.getListenable().addListener(new PathChildrenCacheListener() { @Override public void childEvent(CuratorFramework curatorFramework, PathChildrenCacheEvent pathChildrenCacheEvent) throws Exception { System.out.println("/hui/app2/下的结点发生变化了!"); //获得变化的类型 PathChildrenCacheEvent.Type type = pathChildrenCacheEvent.getType(); //变化的类型是: System.out.println(type); //如果是更新的操作: if (type.equals(PathChildrenCacheEvent.Type.CHILD_UPDATED)) { System.out.println("执行的是更新子节点内容的操作"); byte[] data = pathChildrenCacheEvent.getData().getData(); System.out.println("更新后的内容是:" + new String(data)); } } }); //开始监听 pathChildrenCache.start(); while (true) { } }
Watch监听-TreeCache(监听指定结点以及子节点)
@Test//监听指定结点以及子节点的变化 public void testTreeCache() throws Exception { //1获得Treecache的对象: TreeCache treeCache = new TreeCache(client, "/app1"); //2.怎么监听? treeCache.getListenable().addListener(new TreeCacheListener() { @Override public void childEvent(CuratorFramework curatorFramework, TreeCacheEvent treeCacheEvent) throws Exception { TreeCacheEvent.Type type = treeCacheEvent.getType(); System.out.println("发生了" + type + "类型的变化"); byte[] data = treeCacheEvent.getData().getData(); System.out.println("treecache发生的变化是:" + new String(data)); } }); //开启监听 treeCache.start(); while (true) { } }
注意:当捕获监听获得数据的时候是使用事件连续使用两次getData(),方法获得的数据
迎风少年