• Zookeeper(四)Spring整合Zookeeper【监听器篇】


    一、引言

      我们在前面的学习中知道了zk主要是由文件系统数据结构+监听通知机制组成的,上一篇已经介绍了对zk进行的基础操作,这一篇我想写一下Curator是如何帮我们实现监听功能的。

    二、watch的传统方式实现【标准观察模式】

      现在我们先看看Curator对传统方式watch是如何进行实现的:

      弊端:由于watch机制触发一次就会失效,这种方式不能直接实现循环监听,需要从代码层面做成循环监听的模式,不是很推荐,可以当做了解:

    /**
     * Curator客户端实现watch监听测试类
     * PS:利用Watcher来对节点进行监听操作,但此监听操作只能监听一次,与原生API并无太大差异。【了解即可,一般情况不推荐使用】
     *
     * @author 有梦想的肥宅
     * @date 2021/08/18
     */
    public class CuratorWatchDemo {
    
        public static void main(String[] args) throws Exception {
            //1、定义需要监听的节点
            String path = "/watchDemo";
    
            //2、获取Curator客户端并设置监听事件
            CuratorFramework curatorFramework = ZookeeperClientUtil.getCuratorFramework();
            curatorFramework.getData().usingWatcher(new Watcher() {
                @Override
                public void process(WatchedEvent watchedEvent) {
                    //PS:当节点发生变动的时候会打印这段话【有梦想的肥宅】
                    System.out.println("【有梦想的肥宅】监听器watchedEvent:" + watchedEvent);
                }
            }).forPath(path);
    
            //3、模拟第一次修改被监听的节点【watch生效】
            curatorFramework.setData().forPath(path, "【有梦想的肥宅】第1次被监听啦~".getBytes());
    
            //4、模拟第二次修改被监听的节点【watch已失效】
            curatorFramework.setData().forPath(path, "【有梦想的肥宅】第2次被监听啦~".getBytes());
    
            //5、关闭客户端连接
            curatorFramework.close();
        }
    
    }

    三、基于cache实现监听的实现【缓存监听模式】

      定义:一种基于本地缓存视图的Cache机制并与远程Zookeeper视图的对比过程,来实现对Zookeeper服务端事件监听。

      分类:

    • Path Cache【子节点监听器】
    • Node Cache【当前节点监听器】
    • Tree Cache【综合监听器】

    Path Cache

      观察ZNode的子节点并缓存状态,如果ZNode的子节点被创建,更新或者删除,那么Path Cache会更新缓存,并且触发事件给注册的监听器。

    Node Cache

      观察ZNode自身,如果ZNode节点本身被创建,更新或者删除,那么Node Cache会更新缓存,并触发事件给注册的监听器。 

    Tree Cache

      可以看做是上两种的合体,Tree Cache观察的是ZNode及子节点。

    代码演示

    /**
     * Curator客户端实现对缓存设置监听器的测试类
     * PS:Cache事件监听可以理解为一个本地缓存视图与远程Zookeeper视图的对比过程。Cache提供了反复注册的功能【反复监听】。
     *
     * @author 有梦想的肥宅
     * @date 2021/08/18
     */
    public class CuratorCacheListenerDemo {
    
        public static void main(String[] args) throws Exception {
    
            String cachePath = "/cacheListenerDemo";
            //1、创建连接
            CuratorFramework curatorFramework = ZookeeperClientUtil.getCuratorFramework();
    
            //2、创建cachePath
            curatorFramework.create().creatingParentContainersIfNeeded().withMode(CreateMode.PERSISTENT).forPath(cachePath, "this cache listener".getBytes());
    
            //3、创建PathChildrenCache【路径监听,用于观察其下子节点变更】【cache有3种:Path Cache、Node Cache、Tree Cache这里只演示其中一种】
            PathChildrenCache pathChildrenCache = new PathChildrenCache(curatorFramework, cachePath, true);//true代表缓存数据到本地
            pathChildrenCache.start(PathChildrenCache.StartMode.BUILD_INITIAL_CACHE);//BUILD_INITIAL_CACHE 代表使用同步的方式进行缓存初始化。
            pathChildrenCache.getListenable().addListener((cf, event) -> {
                //4、获取到事件信息,并根据事件类型输出
                PathChildrenCacheEvent.Type eventType = event.getType();
                switch (eventType) {
                    case CONNECTION_RECONNECTED:
                        pathChildrenCache.rebuild();
                        System.out.println("【有梦想的肥宅】重新建立连接!");
                        break;
                    case CONNECTION_SUSPENDED:
                        System.out.println("【有梦想的肥宅】暂停/阻塞连接!");
                        break;
                    case CONNECTION_LOST:
                        System.out.println("【有梦想的肥宅】连接断开!");
                        break;
                    case CHILD_ADDED:
                        System.out.println("【有梦想的肥宅】添加子节点!");
                        break;
                    case CHILD_UPDATED:
                        System.out.println("【有梦想的肥宅】更新子节点!");
                        break;
                    case CHILD_REMOVED:
                        System.out.println("【有梦想的肥宅】删除子节点!");
                        break;
                    default:
                }
            });
    
            //5、这里让线程沉睡以等待listener被调用,此时可以直接操作服务器上的节点,在控制台就会打印触发对应事件的内容了
            Thread.sleep(60 * 60 * 1000);
    
            //6、最后关闭路径监听
            pathChildrenCache.close();
        }
    
    }
  • 相关阅读:
    项目--Asp.net全局变量的设置和读(web.config 和 Gloab)
    项目--后台代码提示
    项目--给项目添加提示声音
    项目--正则表达式
    项目--HTML Canvas 和 jQuery遍历
    项目--用户自定义控件
    Bzoj2120/洛谷P1903 数颜色(莫队)
    Poj2482 Stars in Your Window(扫描线)
    Poj2182 Lost Cows(玄学算法)
    Poj3468 A Simple Problem with Integers (分块)
  • 原文地址:https://www.cnblogs.com/riches/p/15157324.html
Copyright © 2020-2023  润新知