关于Zookeeper Watcher使用注意事项

Watcher是Zookeeper中实现的事件通知机制,当发生变动的时候会通知Client,Zookeeper中Client操作注册的Watcher都为一次性Watcher,除去特殊事件类型,事件类型如下:
None (-1),
NodeCreated (1),
NodeDeleted (2),
NodeDataChanged (3),
NodeChildrenChanged (4);
当类型为None时,主要是 Session expired / connection loss/  auth failed的时候触发的事件,该类型事件的Watcher会在Zookeeper Client重新连接后再次注册,不会丢弃
 
所有注册的Watcher在Client中会加入到waitEvent队列中,只有得到事件通知并且非None类型的事件的时候才会丢弃,并且被GC回收,因为Watcher是一次性通知,所以在通常情况的使用是
每次都New一个新的Watcher注册在服务端,此时如果Watcher过多则会导致OutOfMemoryError: Java heap space。错误代码如下:
 
public class TestLock {
public static void main(String[] args) throws InterruptedException, IOException {
        Configuration conf = SearcherConfiguration.create();   
        ZookeeperClient zk = SearcherUtils.getZKClient(conf
                .get("searcher.thinkingguide.zk.address"), conf.getInt(
                "searcher.thinkingguide.zk.timeout", 3000), conf
                .get("searcher.thinkingguide.zk.lock.dir"), conf
                .get("searcher.thinkingguide.zk.root.dir"), conf
                .get("searcher.thinkingguide.zk.id.node"));
        while(true){
            try {
                zk.exists("/dd", new TestWatcher());
            } catch (KeeperException e) {
                e.printStackTrace();
            }
            Thread.sleep(30);
        }
    }
    static class TestWatcher implements Watcher{
        private long[] test;
        public TestWatcher(){
            this.test = new long[1000000]; //创建一个占用Client大内存的数组,以便测试内存溢出
        }
        @Override
        public void process(WatchedEvent event) {
            System.out.println("===============");
        }
    }
}
 
以上示例在运行几分钟之后就会出现OutOfMemoryError: Java heap space。所以在使用Zookeeper Watcher的时候一定要注意这点。
 
建议做法是在循环中使用wait,并且在Watcher触发的时候notify()。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值