ZooKeeper常用客户端有三种:原生客户端、zkClient、curator
项目中使用前,需要导入相关依赖
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.12</version> </dependency> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.10</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>4.0.0</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>4.0.0</version> </dependency> </dependencies>
1. 原生客户端
1.1 创建会话
1.1.1 不使用监听
public class TestCreateSession { /*服务地址*/ private static final String ZK_SERVER = "127.0.0.1:2181"; @Test public void createSession2() throws IOException { ZooKeeper zk = new ZooKeeper(ZK_SERVER, 50000, null); System.out.println("zk.getState() = " + zk.getState()); } }
zk.getState() = CONNECTING
通过之前的学习可以知道,CONNECTING标志客户端正在连接,并不能确保已经连接上zk服务。可能发生还没有连接到zk服务就进行对zk访问的情况
1.1.2 使用监听
public class TestCreateSession { /*服务地址*/ private static final String ZK_SERVER = "127.0.0.1:2181"; /*倒计时器*/ private CountDownLatch latch = new CountDownLatch(1); @Test public void createSession() throws IOException, InterruptedException { ZooKeeper zk = new ZooKeeper(ZK_SERVER, 50000, new Watcher() { @Override public void process(WatchedEvent event) { if (event.getState() == Event.KeeperState.SyncConnected){/*确保zk已连接*/ latch.countDown(); } } }); latch.await(); System.out.println("zk.getState() = " + zk.getState()); } }
zk.getState() = CONNECTED
使用监听机制可以确保在ZooKeeper初始化完成前进行等待,初始化完成再进行后续操作
1.2 客户端基本操作
public class TestJavaApi implements Watcher { /*zk服务地址*/ private static final String ZK_SERVER = "127.0.0.1:2181"; /*会话连接超时时间*/ private static final int SESSION_TIMEOUT = 50000; /*指定目录【节点】*/ private static final String ZK_PATH = "/zkDir"; /*客户端连接会话*/ private ZooKeeper zk = null; /*倒计时器*/ private CountDownLatch latch = new CountDownLatch(1); /** * 事件被触发时的动作 * @param event 事件 */ @Override public void process(WatchedEvent event) { System.out.println("收到事件通知:" + zk.getState() +"\n"); if (event.getState() == Event.KeeperState.SyncConnected){ latch.countDown(); } } /** * 创建zk会话连接 * @param connectString zk服务器地址列表,可以是"地址1,地址2,...." * @param sessionTimeout Session超时时间 */ public void createZkSession(String connectString, int sessionTimeout){ try { zk = new ZooKeeper(connectString,sessionTimeout,this); latch.await(); System.out.println("zk.getState() = " + zk.getState()); } catch (IOException|InterruptedException e) { System.out.println("连接创建失败"); e.printStackTrace(); } } /** * 关闭zk会话 */ public void releaseSession(){ try { zk.close(); } catch (InterruptedException e) { e.printStackTrace(); } } /** * 创建节点【目录、文件】 * @param path 节点 * @param data 节点数据 * @return */ public boolean createNode(String path,String data){ try { String node = zk.create(path/*节点path*/, data.getBytes()/*节点数据*/, ZooDefs.Ids.OPEN_ACL_UNSAFE/*权限控制 OPEN_ACL_UNSAFE相当于world:anyone*/, CreateMode.EPHEMERAL)/*临时节点*/; System.out.println("节点创建成功,node = " + node); return true; } catch (KeeperException|InterruptedException e) { System.out.println("节点创建失败"); e.printStackTrace(); } return false; } /** * 获取节点数据 * @param path 节点路径 * @return */ public String readNode(String path){ try { byte[] data = zk.getData(path, true, null); String nodeData = new String(data,"utf-8"); //System.out.println("获取"+path+"节点数据:"+nodeData); return nodeData; } catch (KeeperException | InterruptedException | UnsupportedEncodingException e) { e.printStackTrace(); return null; } } /** * 修改节点数据 * @param path 节点path * @param newData 节点新数据 * @return */ public boolean writeNode(String path,String newData){ try { Stat stat = zk.setData(path, newData.getBytes(), -1); System.out.println("节点["+path+"]修改成功"); return true; } catch (KeeperException|InterruptedException e) { e.printStackTrace(); } return false; } /** * 删除指定节点 * @param path 节点path */ public void deleteNode(String path){ try { zk.delete(path,-1); System.out.println("节点["+path+"]删除成功"); } catch (InterruptedException|KeeperException e) { System.out.println("节点["+path+"]删除失败"); e.printStackTrace(); } } public static void main(String[] args) { TestJavaApi api = new TestJavaApi(); api.createZkSession(ZK_SERVER,SESSION_TIMEOUT); if(api.createNode(ZK_PATH,"初始节点内容")){ System.out.println("第一次读"+ZK_PATH+"节点数据:"+api.readNode(ZK_PATH)); api.writeNode(ZK_PATH,"修改ZK_PATH节点数据"); System.out.println("第二次读"+ZK_PATH+"节点数据:"+api.readNode(ZK_PATH)); api.deleteNode(ZK_PATH); } api.releaseSession(); } }
收到事件通知:CONNECTED
zk.getState() = CONNECTED
节点创建成功,node = /zkDir
第一次读/zkDir节点数据:初始节点内容
收到事件通知:CONNECTED
节点[/zkDir]修改成功
第二次读/zkDir节点数据:修改ZK_PATH节点数据
收到事件通知:CONNECTED
节点[/zkDir]删除成功
1.3 watch机制
1.4 ZooKeeper认证机制
2. zkClient
2.1 基本操作
2.2 监听机制
3. curator
3.1 基本操作
3.2 监听机制