package com.test.zk; import org.apache.zookeeper.*; import org.apache.zookeeper.data.Stat; import java.io.IOException; import java.util.List; import java.util.concurrent.CountDownLatch; public class BaseZookeeper implements Watcher { public ZooKeeper zooKeeper; private static final int SESSION_TIME_OUT = 6000; private CountDownLatch countDownLatch = new CountDownLatch(1); /** * 链接zookeeper * * @param host * @throws IOException * @throws InterruptedException */ public void connectZookeeper(String host) throws IOException, InterruptedException { zooKeeper = new ZooKeeper(host, SESSION_TIME_OUT, this); countDownLatch.await(); System.out.println("zookeeper connect ok"); } /** * 实现watcher的接口方法,当链接zookeeper成功后,zookeeper会经过此方法通知watcher * 此处为若是接受到链接成功的event,则countDown,让当前线程继续其余事情。 */ @Override public void process(WatchedEvent event) { if (event.getState() == Event.KeeperState.SyncConnected) { System.out.println("watcher received event"); countDownLatch.countDown(); } } /** * 根据路径建立节点,而且设置节点数据 * * @param path * @param data * @return * @throws KeeperException * @throws InterruptedException */ public String createNode(String path, byte[] data) throws KeeperException, InterruptedException { return this.zooKeeper.create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); } /** * 根据路径获取全部孩子节点 * * @param path * @return * @throws KeeperException * @throws InterruptedException */ public List<String> getChildren(String path) throws KeeperException, InterruptedException { return this.zooKeeper.getChildren(path, false); } public Stat setData(String path, byte[] data, int version) throws KeeperException, InterruptedException { return this.zooKeeper.setData(path, data, version); } /** * 根据路径获取节点数据 * * @param path * @return * @throws KeeperException * @throws InterruptedException */ public byte[] getData(String path) throws KeeperException, InterruptedException { return this.zooKeeper.getData(path, false, null); } /** * 删除节点 * * @param path * @param version * @throws InterruptedException * @throws KeeperException */ public void deletNode(String path, int version) throws InterruptedException, KeeperException { this.zooKeeper.delete(path, version); } /** * 关闭zookeeper链接 * * @throws InterruptedException */ public void closeConnect() throws InterruptedException { if (null != zooKeeper) { zooKeeper.close(); } } }
package com.test.zk; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.Arrays; import java.util.List; public class ZookeeperTest { private static Logger logger = LoggerFactory.getLogger(ZookeeperTest.class); public static void main(String[] args) { logger.info("main begin...."); try { BaseZookeeper baseZookeeper = new BaseZookeeper(); String host = "127.0.0.1:8080";//本地zookeeper端口号改成8080了 // 链接zookeeper baseZookeeper.connectZookeeper(host); System.out.println("--------connect zookeeper ok-----------"); // 建立节点 /*byte [] data = {1, 2, 3, 4, 5}; String result = baseZookeeper.createNode("/test", data); System.out.println(result); System.out.println("--------create node ok-----------");*/ // 获取某路径下全部节点 List<String> children = baseZookeeper.getChildren("/"); for (String child : children) { logger.info(child); } logger.info("--------get children ok-----------"); // 获取节点数据 /* byte [] nodeData = baseZookeeper.getData("/test"); logger.info(new String(nodeData,"UTF-8")); logger.info("--------get node data ok-----------");*/ // 更新节点数据 byte[] data = "测试".getBytes("UTF-8"); baseZookeeper.setData("/test", data, 2);//版本号为当前的版本 System.out.println("--------set node data ok-----------"); byte[] nodeData = baseZookeeper.getData("/test"); System.out.println(new String(nodeData,"UTF-8")); System.out.println("--------get node new data ok-----------"); baseZookeeper.closeConnect(); System.out.println("--------close zookeeper ok-----------"); } catch (Exception e) { logger.error("...zookeeper操做出错....",e); } } }
pom.xmlhtml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.test</groupId> <artifactId>test-demo</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>test-demo Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <junit.version>3.8.1</junit.version> <zkclient.version>2.1.1</zkclient.version> <zookeeper.version>3.4.6</zookeeper.version> <slf4j-log4j12.version>1.7.12</slf4j-log4j12.version> </properties> <dependencies> <!-- <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> --> <!-- <dependency> <groupId>com.github.adyliu</groupId> <artifactId>zkclient</artifactId> <version>${zkclient.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.6.1</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.6.1</version> <scope>compile</scope> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.16</version> <scope>compile</scope> </dependency> --> <!--zookeeper java客户端--> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>${zookeeper.version}</version> <exclusions> <exclusion> <groupId>jline</groupId> <artifactId>jline</artifactId> </exclusion> <exclusion> <groupId>io.netty</groupId> <artifactId>netty</artifactId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> <exclusion> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </exclusion> </exclusions> </dependency> <!--日志相关--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${slf4j-log4j12.version}</version> </dependency> </dependencies> <build> <finalName>test-demo</finalName> </build> </project>
1、ZooKeeper 节点java
是有生命周期的,这取决于节点的类型。在 ZooKeeper 中,节点类型能够分为持久节点(PERSISTENT )、临时节点(EPHEMERAL),以及时序节点(SEQUENTIAL ),具体在节点建立过程当中,通常是组合使用,能够生成如下 4 种节点类型。node
持久节点(PERSISTENT)git
所谓持久节点,是指在节点建立后,就一直存在,直到有删除操做来主动清除这个节点——不会由于建立该节点的客户端会话失效而消失。github
持久顺序节点(PERSISTENT_SEQUENTIAL)apache
这类节点的基本特性和上面的节点类型是一致的。额外的特性是,在ZK中,每一个父节点会为他的第一级子节点维护一份时序,会记录每一个子节点建立的前后顺序。 基于这个特性,在建立子节点的时候,能够设置这个属性,那么在建立节点过程当中,ZK会自动为给定节点名加上一个数字后缀,做为新的节点名。这个数字后缀的 范围是整型的最大值。api
临时节点(EPHEMERAL)app
和持久节点不一样的是,临时节点的生命周期和客户端会话绑定。也就是说,若是客户端会话失效,那么这个节点就会自动被清除掉。注意,这里提到的是会话失效,而非链接断开。另外,在临时节点下面不能建立子节点。maven
临时顺序节点(EPHEMERAL_SEQUENTIAL)分布式
能够用来实现分布式锁
客户端调用create()方法建立名为“_locknode_/guid-lock-”的节点,须要注意的是,这里节点的建立类型须要设置为EPHEMERAL_SEQUENTIAL。客户端调用getChildren(“_locknode_”)方法来获取全部已经建立的子节点,注意,这里不注册任何Watcher。客户端获取到全部子节点path以后,若是发现本身在步骤1中建立的节点序号最小,那么就认为这个客户端得到了锁。若是在步骤3中发现本身并不是全部子节点中最小的,说明本身尚未获取到锁。此时客户端须要找到比本身小的那个节点,而后对其调用exist()方法,同时注册事件监听。以后当这个被关注的节点被移除了,客户端会收到相应的通知。这个时候客户端须要再次调用getChildren(“_locknode_”)方法来获取全部已经建立的子节点,确保本身确实是最小的节点了,而后进入步骤3。