ZooKeeper原生Api基本操作

 XML Code 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203

 

package com.lyzx.zk.test.crudeApi;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class ZkTest1 {
    private static final String URL = "192.168.29.167:2181,192.168.29.168:2181,192.168.29.169:2181";
    private static final int SESSION_TIMEOUT = 3000;
    private ZooKeeper zk = null;
    private final String zkPath = "/zkApi";
    
    //获取一个ZooKeeper实例
    @Before
    public void getZookeeper(){
        try {
            zk = new ZooKeeper(URL,SESSION_TIMEOUT, new Watcher() {
                @Override
                public void process(WatchedEvent event) {
                    //NodeChildrenChanged
                    //NodeCreated
                    //NodeDataChanged
                    //NodeDeleted
                    //None
                    System.err.println("初始化时的Watch被触发:"+event.getType());
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    @After
    public void closeZk() throws InterruptedException{
        if(null != zk){
            zk.close();
        }
    }
    
    /**
     * 创建一个节点
     * @throws InterruptedException
     * @throws KeeperException
     */
    @Test
    public void testCreateNode() throws InterruptedException, KeeperException{
        zk.create(zkPath,"first".getBytes(),Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
    }
    
    @Test
    public void testDeleteNode() throws InterruptedException, KeeperException{
        /**
         * ZooKeeper.delete(String path, int version)
         * 如果version传-1 表示忽略版本号删除节点
         * 如果传了version 但是和zk里的版本不一致会包抛异常表示版本不一致并没有被删除
         * 这种情况可以在catch中处理
         * version参数的作用
         *  可能有的客户端只想删除自己创建/修改的数据,如果这个节点被别人修改过则不删除
         */
        zk.delete(zkPath,-1);
    }
    
    @Test
    public void testGetData01() throws KeeperException, InterruptedException{
        //直接取值
        byte[] data = zk.getData(zkPath,null,null);
        System.out.println(">>:"+new String(data));
    }
    
    /**
     * Watch是一次性的,即当监听某一个节点后这个节点发生了对应的变化后置通知该客户端一次
     * 当这个节点第二次发生对应的变化后就不再通知这个客户端
     * 
     * 这样做的目的是防止当某个节点被很多客户端监听并且这个节点变化很频繁
     * 这种情况下服务器就只需要向监听该节点的客户端推送一次通知即可
     * 如果某个客户端需要一直监听某个节点的变化时,就需要客户端反复注册Watch
     * 
     * 但是这样做有一个问题就是如果节点A频繁的变化
     * 当客户端C监听到A有变化后再次注册监听之前这个节点有可能有发生了变化
     * 即客户端C在前后两次监听之间的时间间隔中A有发生了变化
     * 亦即客户端C收到的通知并不是所有的变化通知,会有部分变化服务端没有推送给客户端
     * (主要是客户端不能实时的监听节点A的每一次变化)
     * 
     * getData(final String path, Watcher watcher, Stat stat)
     * 参数说明:
     * watcher:一个监听事件
     *      当注册这个监听事件后会得到一次相应的通知
     *      NodeDataChanged=> 节点的数据被修改
     *      NodeDeleted =>  节点被删除
     * stat:是存储于path节点相关的数据类似于元数据
     *      就是在命令行中使用get 命令后看到的除了第一行之外的其他数据
     *      这个方法之所以这样使用,我的猜测是java不支持多返回值
     *      此时,传递一个应用类型,其在方法内部改变这个引用的属性值,在方法外依然可以看到这些改变到的数据
     */
    @Test
    public void testGetData02(){
        try {
            Stat stat = new Stat();
            byte[] data = zk.getData(zkPath,new Watcher(){
                @Override
                public void process(WatchedEvent event) {
                    System.out.println("::"+event.getType());
                    EventType t = event.getType();
                    if(t == EventType.NodeChildrenChanged){
                        System.out.println("子节点被改变");
                    }else if(t == EventType.NodeDataChanged){
                        System.out.println("节点数据被改变");
                    }else if(t == EventType.NodeDeleted){
                        System.out.println("节点被删除");
                    }else if(t == EventType.NodeCreated){
                        System.out.println("节点被创建");
                    }else {
                        System.out.println("else:"+t);
                    }
                }
            },stat);
            System.out.println("取出的数据:"+new String(data));
            System.out.println(stat.getVersion());
        } catch (KeeperException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        try {
            Thread.sleep(Long.MAX_VALUE);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    /**
     * @throws KeeperException
     * @throws InterruptedException
     * 
     * String path, boolean watch
     * 参数说明:
     *  watch:表示需不需要使用监听器监听这个节点
     *      如果传入true就表示需要监听
     *      那么就会使用创建ZooKeeper这个实例时所创建的Watcher做监听
     *      NodeCreated      =>  节点别创建
     *      NodeDataChanged  =>  节点数据被修改
     *      NodeDeleted      =>  节点被删除
     *  这3个事件发生时都会被触发
     *  其中NodeCreated表示这个节点不存在当创建一个名为path的节点时通知Watcher
     *  即这个方法可以检测一个不存在的节点并接收通知
     */
    @Test
    public void  testExsits() throws KeeperException, InterruptedException{
        Stat stat = zk.exists("/zkApi2",true);
        if(null == stat){
            System.out.println("节点不存在");
        }else{
            System.out.println("节点存在,,,哈哈哈!");
        }
        
        try {
            Thread.sleep(Long.MAX_VALUE);
        }catch(InterruptedException e){
            e.printStackTrace();
        }
    }
    
    @Test
    public void testSetData() throws KeeperException, InterruptedException{
        Stat stat = zk.setData(zkPath,"myZk".getBytes(),-1);
        //返回修改后的元数据
        System.out.println(stat.getVersion());
    }
    
    /**
     * 
     * @throws KeeperException
     * @throws InterruptedException
     * 
     * getChildren(String path, boolean watch)
     * 当watch为true时表示当发生了NodeChildrenChanged事件时由zk对象时附加的Watch来处理
     * NodeChildrenChanged包括
     *  >>直接子节点被删除
     *  >>直接子节点被新建
     *      >>其中子节点的数据改变不会触发Watcher
     */
    @Test
    public void testGetChildren() throws KeeperException,InterruptedException{
        List<String> list = zk.getChildren(zkPath,true);
        System.out.println(">>:"+list.size());
        for(String v : list){
            System.out.println(v);
        }
        TimeUnit.SECONDS.sleep(Long.MAX_VALUE);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值