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); } } |