Zookeeper框架Curator之事件监听-yellowcong

Curator通过NodeCache、PathChildrenCache、TreeCache 对节点变化进行监听操作,以前的Zookeeper的Wacher效果差,而Curator的做法是以牺牲内存的方法来换取效率,通过NodeCache的方法,监听缓存的数据,比较缓存数据和Zookeeper服务器数据,来判断事件

1.Curator Cache 与原生ZooKeeper Wacher区别

原生的ZooKeeper Wacher是一次性的:一个Wacher一旦触发就会被移出,如果你想要反复使用Wacher,就要在Wacher被移除后重新注册,使用起来很麻烦。使用Curator Cache 可以反复使用Wacher了。

2.Curator Cache 和Curator Wacher区别

2.相关类

Curator Cache主要提供了一下三组类,分别用于实现对节点的监听,子节点的监听和二者的混合:

1.NodeCache,NodeCacheListener,ChildData,节点创建,节点数据内容变更,不能监听节点删除

2.PathChildrenCache,PathChildrenCacheListener,PathChildrenCacheEvent监听指定节点的子节点的变更包括添加,删除,子节点数据数据变更这三类。这个监听用得多

3.TreeCache,TreeCacheListener,TreeCacheEvent,TreeCacheSelector

NodeCacheListener案例

这个节点监听操作,不会监听删除事件,而且这种监听操作用到的场景很少

package com.yellowcong.zookeeper.curator;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.ChildData;
import org.apache.curator.framework.recipes.cache.NodeCache;
import org.apache.curator.framework.recipes.cache.NodeCacheListener;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;

/**
 * 创建日期:2017年10月14日 <br/>
 * 创建用户:yellowcong <br/>
 * 功能描述:  
 */
public class CuratorWatcherDemo {

    private static final String CONNECT_PATH = "192.168.66.110:2181,192.168.66.110:2182,192.168.66.110:2183";

    // Session 超时时间
    private static final int SESSION_TIME_OUT = 60000;

    //连接超时
    private static final int CONNECT_TIME_OUT = 5000;

    public static void main(String[] args) throws Exception {

        //1、尝试策略
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(5000, 10);

        //2、创建CuratorFramework 工厂类
        CuratorFramework cf = CuratorFrameworkFactory.builder()
            .connectString(CONNECT_PATH)
            .connectionTimeoutMs(SESSION_TIME_OUT)
            .sessionTimeoutMs(CONNECT_TIME_OUT)
            .retryPolicy(retryPolicy)
            .build();

        //3、启动连接
        cf.start();

        //4、建立一个Cache缓存
        final NodeCache cache = new NodeCache(cf, "/curator/nodecache",false);
        cache.start();

        ExecutorService pool = Executors.newCachedThreadPool();

        //创建监听器
        cache.getListenable().addListener(new NodeCacheListener() {

            public void nodeChanged() throws Exception {
                ChildData data = cache.getCurrentData();
                System.out.println("修改路径\t"+data.getPath());
                System.out.println("数据类容\t"+new String(data.getData()));
                System.out.println("状态\t"+data.getStat());
                System.out.println("-------------------------");
            }
        },pool);

        //创建节点
        Thread.sleep(1000);
        cf.create().withMode(CreateMode.PERSISTENT).forPath("/curator/nodecache","nodecache  test".getBytes());

        //数据修改
        Thread.sleep(1000);
        cf.setData().forPath("/curator/nodecache","update".getBytes());

        //获取节点数据
        Thread.sleep(1000);
        byte [] data = cf.getData().forPath("/curator/nodecache");
        System.out.println(new String(data));


        //删除节点
        cf.delete().deletingChildrenIfNeeded().forPath("/curator/nodecache");
    }
}

PathChildrenCacheListener 案例

PathChildrenCache.StartMode
BUILD_INITIAL_CACHE //同步初始化客户端的cache,及创建cache后,就从服务器端拉入对应的数据(这个是NodeCache使用的方式)
NORMAL //异步初始化cache
POST_INITIALIZED_EVENT //异步初始化,初始化完成触发事件PathChildrenCacheEvent.Type.INITIALIZED (这个方式是 PathChildrenCacheListener 使用的)

dataIsCompressed 是否进行数据压缩 ,如果设定为false,如果在节点修改了数据,就不会直接存在缓存中,需要自己重新取一遍,一般设置为true

package com.yellowcong.zookeeper.curator;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.ChildData;
import org.apache.curator.framework.recipes.cache.PathChildrenCache;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
import org.apache.curator.framework.recipes.cache.PathChildrenCache.StartMode;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;

/**
 * 创建日期:2017年10月14日 <br/>
 * 创建用户:yellowcong <br/>
 * 功能描述:  
 */
public class CuratorWatcherDemo2 {

    private static final String CONNECT_PATH = "192.168.66.110:2181,192.168.66.110:2182,192.168.66.110:2183";

    // Session 超时时间
    private static final int SESSION_TIME_OUT = 60000;

    //连接超时
    private static final int CONNECT_TIME_OUT = 5000;

    public static void main(String[] args) throws Exception {

        //1、尝试策略
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(5000, 10);

        //2、创建CuratorFramework 工厂类
        CuratorFramework cf = CuratorFrameworkFactory.builder()
            .connectString(CONNECT_PATH)
            .connectionTimeoutMs(SESSION_TIME_OUT)
            .sessionTimeoutMs(CONNECT_TIME_OUT)
            .retryPolicy(retryPolicy)
            .build();

        //3、启动连接
        cf.start();

        //4、建立一个Cache缓存 ,第三个参数是 dataIsCompressed 是否进行数据压缩  ,需要配置为true
        //如果第三个参数设置为 false,则不接受节点变更后的数据
        final PathChildrenCache cache = new PathChildrenCache(cf, "/curator", true);

        //5、设定监听的模式 ,异步初始化,初始化完成触发事件 PathChildrenCacheEvent.Type.INITIALIZED
        cache.start(StartMode.POST_INITIALIZED_EVENT);

        ExecutorService pool = Executors.newCachedThreadPool();

        //创建监听器
        cache.getListenable().addListener(new PathChildrenCacheListener() {

            public void childEvent(CuratorFramework cf, PathChildrenCacheEvent event) throws Exception {
                // TODO Auto-generated method stub
                ChildData data = event.getData();
                System.out.println("路径\t"+data.getPath());
                System.out.println("更改数据\t"+new String(data.getData()));
                System.out.println("节点状态\t"+data.getStat());
                System.out.println(event.getType());
                switch (event.getType()) {
                //初始化会触发这个事件
                case INITIALIZED:
                    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:
                    break;
                }

                System.out.println("----------------------------------");
            }
        });

        //判断节点是否存在,然后删除掉
        Stat stat = cf.checkExists().forPath("/curator/nodecache2");
        if(stat != null){
            Thread.sleep(1000);
            cf.delete().deletingChildrenIfNeeded().forPath("/curator/nodecache2");
        }

        //创建节点
        Thread.sleep(1000);
        cf.create().withMode(CreateMode.PERSISTENT).forPath("/curator/nodecache2","nodecache  test".getBytes());

        //数据修改
        Thread.sleep(1000);
        cf.setData().forPath("/curator/nodecache2","update".getBytes());

        //获取节点数据
        Thread.sleep(1000);
        byte [] data = cf.getData().forPath("/curator/nodecache2");
        System.out.println(new String(data));


        //删除节点
        Thread.sleep(1000);
        cf.delete().deletingChildrenIfNeeded().forPath("/curator/nodecache2");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

狂飙的yellowcong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值