Zookeeper系列三:Zookeeper客户端的使用(Zookeeper原生API如何进行调用、ZKClient、Curator)和Zookeeper会话
一、Zookeeper原生API如何进行调用
准备工作:
首先在新建一个maven项目ZK-Demo,然后在pom.xml里面引入zk的依赖
- <dependency>
- <groupId>org.apache.zookeeper</groupId>
- <artifactId>zookeeper</artifactId>
- <version>3.4.10</version>
- </dependency>
1. 连接zk并监听事件
- package com.study.demo.zk;
- import java.io.IOException;
- import java.util.concurrent.CountDownLatch;
- import org.apache.zookeeper.WatchedEvent;
- import org.apache.zookeeper.Watcher;
- import org.apache.zookeeper.Watcher.Event.KeeperState;
- import org.apache.zookeeper.ZooKeeper;
- //连接zk并监听事件
- public class ZKDemo implements Watcher {
- private static final CountDownLatch cdl = new CountDownLatch(1);
- public static void main(String[] args) throws IOException {
- ZooKeeper zk = new ZooKeeper("192.168.152.130:2181", 5000, new ZKDemo());
- System.out.println(zk.getState());
- try {
- cdl.await();
- } catch (Exception e) {
- System.out.println("ZK Session established.");
- }
- }
- //监听到事件时进行处理
- public void process(WatchedEvent event) {
- System.out.println("Receive watched event:" + event);
- if (KeeperState.SyncConnected == event.getState()) {
- cdl.countDown();
- }
- }
- }
输出结果:
CONNECTING
Receive watched event:WatchedEvent state:SyncConnected type:None path:null
2. 创建znode并监听事件
- package com.study.demo.zk;
- import java.io.IOException;
- import java.util.concurrent.CountDownLatch;
- import org.apache.zookeeper.CreateMode;
- import org.apache.zookeeper.KeeperException;
- import org.apache.zookeeper.WatchedEvent;
- import org.apache.zookeeper.Watcher;
- import org.apache.zookeeper.Watcher.Event.KeeperState;
- import org.apache.zookeeper.ZooDefs.Ids;
- import org.apache.zookeeper.ZooKeeper;
- //创建znode并监听事件
- public class ZKOperateDemo implements Watcher {
- private static final CountDownLatch cdl = new CountDownLatch(1);
- public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
- ZooKeeper zk = new ZooKeeper("192.168.152.130:2181", 5000, new ZKOperateDemo());
- cdl.await();
- String path1 = zk.create("/zk-test-", "123".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
- System.out.println("Success create path: " + path1);
- String path2 = zk.create("/zk-test-", "456".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
- System.out.println("Success create path: " + path2);
- }
- //监听到事件时进行处理
- public void process(WatchedEvent event) {
- System.out.println("Receive watched event:" + event);
- if (KeeperState.SyncConnected == event.getState()) {
- cdl.countDown();
- }
- }
- }
输出结果:
Receive watched event:WatchedEvent state:SyncConnected type:None path:null
Success create path: /zk-test-
Success create path: /zk-test-0000000011
3. 改变znode数据并监听事件
- package com.study.demo.zk;
- import java.io.IOException;
- import java.util.concurrent.CountDownLatch;
- import org.apache.zookeeper.CreateMode;
- import org.apache.zookeeper.KeeperException;
- import org.apache.zookeeper.WatchedEvent;
- import org.apache.zookeeper.Watcher;
- import org.apache.zookeeper.Watcher.Event.EventType;
- import org.apache.zookeeper.Watcher.Event.KeeperState;
- import org.apache.zookeeper.ZooDefs.Ids;
- import org.apache.zookeeper.ZooKeeper;
- import org.apache.zookeeper.data.Stat;
- //改变znode数据并监听事件
- public class ZKDataDemo implements Watcher {
- private static final CountDownLatch cdl = new CountDownLatch(1);
- private static ZooKeeper zk = null;
- private static Stat stat = new Stat();
- public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
- zk = new ZooKeeper("192.168.152.130:2181", 5000, new ZKDataDemo());
- cdl.await();
- zk.create("/zk-test", "123".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
- System.out.println(new String(zk.getData("/zk-test", true, stat)));
- zk.getData("/zk-test", true, stat);
- System.out.println(stat.getCzxid() + ", " + stat.getMzxid() + ", " + stat.getVersion());
- zk.setData("/zk-test", "123".getBytes(), -1);
- Thread.sleep(Integer.MAX_VALUE);
- }
- //监听到事件时进行处理
- public void process(WatchedEvent event) {
- if (KeeperState.SyncConnected == event.getState()) {
- if (EventType.None == event.getType() && null == event.getPath()) {
- cdl.countDown();
- } else if (event.getType() == EventType.NodeDataChanged) {
- try {
- System.out.println(new String(zk.getData(event.getPath(), true, stat)));
- System.out.println(stat.getCzxid() + ", " + stat.getMzxid() + ", " + stat.getVersion());
- } catch (Exception e) {
- }
- }
- }
- }
- }
输出结果:
123
4294967354, 4294967354, 0
123
4294967354, 4294967355, 1
4. 改变子节点并监听事件
- package com.study.demo.zk;
- import java.io.IOException;
- import java.util.List;
- import java.util.concurrent.CountDownLatch;
- import org.apache.zookeeper.CreateMode;
- import org.apache.zookeeper.KeeperException;
- import org.apache.zookeeper.WatchedEvent;
- import org.apache.zookeeper.Watcher;
- import org.apache.zookeeper.Watcher.Event.EventType;
- import org.apache.zookeeper.Watcher.Event.KeeperState;
- import org.apache.zookeeper.ZooDefs.Ids;
- import org.apache.zookeeper.ZooKeeper;
- //改变子节点并监听事件
- public class ZKChildrenDemo implements Watcher {
- private static final CountDownLatch cdl = new CountDownLatch(1);
- private static ZooKeeper zk = null;
- public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
- zk = new ZooKeeper("192.168.152.130:2181", 5000, new ZKChildrenDemo());
- cdl.await();
- zk.create("/zk-test", "123".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
- zk.create("/zk-test/c1", "456".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
- List<String> list = zk.getChildren("/zk-test", true);
- for (String str : list)
- System.out.println(str);
- zk.create("/zk-test/c2", "789".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
- Thread.sleep(Integer.MAX_VALUE);
- }
- //监听到事件时进行处理
- public void process(WatchedEvent event) {
- if (KeeperState.SyncConnected == event.getState())
- if (EventType.None == event.getType() && null == event.getPath()) {
- cdl.countDown();
- } else if (event.getType() == EventType.NodeChildrenChanged) {
- try {
- System.out.println("Child: " + zk.getChildren(event.getPath(), true));
- } catch (Exception e) {
- }
- }
- }
- }
输出结果:
c1
Child: [c1, c2]
5. 异步调用并完成回调
- package com.study.demo.zk;
- import java.io.IOException;
- import java.util.List;
- import java.util.concurrent.CountDownLatch;
- import org.apache.zookeeper.AsyncCallback;
- import org.apache.zookeeper.CreateMode;
- import org.apache.zookeeper.KeeperException;
- import org.apache.zookeeper.WatchedEvent;
- import org.apache.zookeeper.Watcher;
- import org.apache.zookeeper.Watcher.Event.EventType;
- import org.apache.zookeeper.Watcher.Event.KeeperState;
- import org.apache.zookeeper.ZooDefs.Ids;
- import org.apache.zookeeper.ZooKeeper;
- import org.apache.zookeeper.data.Stat;
- //异步调用并完成回调
- class ChildrenCallback implements AsyncCallback.Children2Callback {
- public void processResult(int rc, String path, Object ctx, List<String> children, Stat stat) {
- System.out.println(
- "Child: " + rc + ", path: " + path + ", ctx: " + ctx + ", children: " + children + ", stat: " + stat);
- }
- }
- public class ZKChildrenAsyncDemo implements Watcher {
- private static final CountDownLatch cdl = new CountDownLatch(1);
- private static ZooKeeper zk = null;
- public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
- zk = new ZooKeeper("192.168.152.130:2181", 5000, new ZKChildrenAsyncDemo());
- cdl.await();
- zk.create("/zk-test", "123".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
- zk.create("/zk-test/c1", "456".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
- zk.getChildren("/zk-test", true, new ChildrenCallback(), "ok");
- Thread.sleep(Integer.MAX_VALUE);
- }
- //监听到事件时进行处理
- public void process(WatchedEvent event) {
- if (KeeperState.SyncConnected == event.getState())
- if (EventType.None == event.getType() && null == event.getPath()) {
- cdl.countDown();
- } else if (event.getType() == EventType.NodeChildrenChanged) {
- try {
- System.out.println("Child: " + zk.getChildren(event.getPath(), true));
- } catch (Exception e) {
- }
- }
- }
- }
输出结果:
Child: 0, path: /zk-test, ctx: ok, children: [c1], stat: 4294967369,4294967369,1535536716381,1535536716381,0,1,0,0,3,1,4294967370
6. 连接后创建回调
- package com.study.demo.zk;
- import java.io.IOException;
- import java.util.concurrent.CountDownLatch;
- import org.apache.zookeeper.AsyncCallback;
- import org.apache.zookeeper.CreateMode;
- import org.apache.zookeeper.KeeperException;
- import org.apache.zookeeper.WatchedEvent;
- import org.apache.zookeeper.Watcher;
- import org.apache.zookeeper.Watcher.Event.KeeperState;
- import org.apache.zookeeper.ZooDefs.Ids;
- import org.apache.zookeeper.ZooKeeper;
- //连接后创建回调
- class IStringCallback implements AsyncCallback.StringCallback {
- public void processResult(int rc, String path, Object ctx, String name) {
- System.out.println("create path result: [" + rc + ", " + path + "," + ctx + ", real path name: " + name);
- }
- }
- public class ZKAsyncDemo implements Watcher {
- private static final CountDownLatch cdl = new CountDownLatch(1);
- public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
- ZooKeeper zk = new ZooKeeper("192.168.152.130:2181", 5000, new ZKAsyncDemo());
- cdl.await();
- zk.create("/zk-test-", "123".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL, new IStringCallback(),
- new String("I am context"));
- zk.create("/zk-test-", "456".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL,
- new IStringCallback(), new String("I am context"));
- zk.create("/zk-test-", "789".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL,
- new IStringCallback(), new String("I am context"));
- Thread.sleep(Integer.MAX_VALUE);
- }
- //监听到事件时进行处理
- public void process(WatchedEvent event) {
- System.out.println("Receive watched event:" + event);
- if (KeeperState.SyncConnected == event.getState()) {
- cdl.countDown();
- }
- }
- }
输出结果:
Receive watched event:WatchedEvent state:SyncConnected type:None path:null
create path result: [0, /zk-test-,I am context, real path name: /zk-test-
create path result: [-110, /zk-test-,I am context, real path name: null
create path result: [0, /zk-test-,I am context, real path name: /zk-test-0000000016
Chroot命名空间:
主要为了对业务进行隔离性
示例:
Zookeeper client=new Zookeeper(“192.168.56.101:2181/zk-client”, ........)
/zk-client就是Chroot命名空间。Chroot命名空间可以多级
后续的操作都只能在/zk-client及它的子节点下进行,由此进行了业务隔离
二、ZKClient
ZKClient的优点:
1)可以递归创建。在zookeeper命令行和zookeeper的原生API里面得先创建父节点才能创建子节点
2)可以递归删除。在zookeeper命令行和zookeeper的原生API里面得先删除子节点才能删除父节点
3)避免不存在的异常
准备工作:
首先在新建一个maven项目ZK-Demo,然后在pom.xml里面引入ZKClient的依赖
- <dependency>
- <groupId>com.101tec</groupId>
- <artifactId>zkclient</artifactId>
- <version>0.10</version>
- </dependency>
1. ZkClient递归创建顺序节点
- package com.study.demo.client;
- import org.I0Itec.zkclient.ZkClient;
- /**
- *
- * @Description: ZkClient递归创建顺序节点
- * @author leeSmall
- * @date 2018年9月2日
- *
- */
- public class CreateNodeDemo {
- public static void main(String[] args) {
- ZkClient client = new ZkClient("192.168.152.130:2181", 5000);
- String path = "/zk-client/c1";
- // 递归创建顺序节点 true:先创建父节点/zk-client
- client.createPersistent(path, true);
- }
- }
创建成功:
2. ZkClient获取数据并监听事件
- package com.study.demo.client;
- import org.I0Itec.zkclient.IZkDataListener;
- import org.I0Itec.zkclient.ZkClient;
- /**
- *
- * @Description: ZkClient获取数据
- * @author leeSmall
- * @date 2018年9月2日
- *
- */
- public class GetDataDemo {
- public static void main(String[] args) throws InterruptedException {
- String path = "/zk-client";
- ZkClient client = new ZkClient("192.168.152.130:2181", 5000);
- //创建临时节点
- client.createEphemeral(path, "123");
- //注册父节点数据改变的事件
- client.subscribeDataChanges(path, new IZkDataListener() {
- //父节点数据改变事件
- public void handleDataChange(String dataPath, Object data) throws Exception {
- System.out.println(dataPath + " changed: " + data);
- }
- //父节点数据删除事件
- public void handleDataDeleted(String dataPath) throws Exception {
- System.out.println(dataPath + " deleted");
- }
- });
- System.out.println(client.readData(path).toString());
- client.writeData(path, "456");
- Thread.sleep(1000);
- client.delete(path);
- //sleep的目的是为了更好的观察事件变化
- Thread.sleep(Integer.MAX_VALUE);
- }
- }
输出结果:
123
/zk-client changed: 456
/zk-client deleted
3. ZkClient获取子节点数据并监听事件
- package com.study.demo.client;
- import java.util.List;
- import org.I0Itec.zkclient.IZkChildListener;
- import org.I0Itec.zkclient.ZkClient;
- /**
- *
- * @Description: ZkClient获取子节点数据
- * @author leeSmall
- * @date 2018年9月2日
- *
- */
- public class GetChildrenDemo {
- public static void main(String[] args) throws InterruptedException {
- String path = "/zk-client";
- ZkClient client = new ZkClient("192.168.152.130:2181", 5000);
- //注册子节点数据改变的事件
- client.subscribeChildChanges(path, new IZkChildListener() {
- //子节点数据改变事件
- public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception {
- System.out.println(parentPath + "的子发生变化: " + currentChilds);
- }
- });
- //创建顺序节点
- client.createPersistent(path);
- Thread.sleep(1000);
- //获取子节点数据 此时还没有创建获取不到
- System.out.println(client.getChildren(path));
- //在前面的父节点 /zk-client下创建子节点c1
- client.createPersistent(path + "/c1");
- Thread.sleep(1000);
- //删除子节点
- client.delete(path + "/c1");
- Thread.sleep(1000);
- //删除父节点
- client.delete(path);
- Thread.sleep(Integer.MAX_VALUE);
- }
- }
输出结果:
/zk-client的子发生变化: []
[]
/zk-client的子发生变化: [c1]
/zk-client的子发生变化: []
/zk-client的子发生变化: null
三、Curator
curator是连接ZK应用最广泛的工具
原因如下:
1)zk应用场景(分布式锁,Master选举等等),curator包含了这些场景。
2)应用场景出现极端的情况下,curator考虑到处理了。
准备工作:
首先在新建一个maven项目ZK-Demo,然后在pom.xml里面引入curator的依赖
- <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>
1. curator创建连接session
- package com.study.demo.curator;
- import org.apache.curator.RetryPolicy;
- import org.apache.curator.framework.CuratorFramework;
- import org.apache.curator.framework.CuratorFrameworkFactory;
- import org.apache.curator.retry.ExponentialBackoffRetry;
- /**
- *
- * @Description: curator创建连接session
- * @author leeSmall
- * @date 2018年9月2日
- *
- */
- public class CreateSessionDemo {
- public static void main(String[] args) throws InterruptedException {
- RetryPolicy policy = new ExponentialBackoffRetry(1000, 3);
- CuratorFramework client = CuratorFrameworkFactory.builder().connectString("192.168.152.130:2181")
- .sessionTimeoutMs(5000).retryPolicy(policy).build();
- client.start();
- Thread.sleep(Integer.MAX_VALUE);
- }
- }
这里介绍一种算法:Backoff退避算法
有这样一种场景,有多个请求,如果网络出现阻塞,每1分钟重试一次。
20:25 request1(block)
20:26 request2(block)
20:27 request3(block)
当网络通顺的时候,请求都累在一起来发送
20:28 request4(通顺)request2、3、4
那么前面的请求就没有意义了,所以就有了退避算法,按照指数间隔重试,比如第一次1分钟,第二次2分钟......随着时间的推移,重试间隔越长。
2. curator递归创建顺序节点
- package com.study.demo.curator;
- import org.apache.curator.framework.CuratorFramework;
- import org.apache.curator.framework.CuratorFrameworkFactory;
- import org.apache.curator.retry.ExponentialBackoffRetry;
- import org.apache.zookeeper.CreateMode;
- /**
- *
- * @Description: curator递归创建顺序节点
- * @author leeSmall
- * @date 2018年9月2日
- *
- */
- public class CreateNodeDemo {
- public static void main(String[] args) throws Exception {
- String path = "/zk-curator/c1";
- CuratorFramework client = CuratorFrameworkFactory.builder().connectString("192.168.152.130:2181")
- .sessionTimeoutMs(5000).retryPolicy(new ExponentialBackoffRetry(1000, 3)).build();
- client.start();
- client.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).forPath(path, "test".getBytes());
- }
- }
创建成功:
3. curator异步创建临时节点
- package com.study.demo.curator;
- import java.util.concurrent.CountDownLatch;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import org.apache.curator.framework.CuratorFramework;
- import org.apache.curator.framework.CuratorFrameworkFactory;
- import org.apache.curator.framework.api.BackgroundCallback;
- import org.apache.curator.framework.api.CuratorEvent;
- import org.apache.curator.retry.ExponentialBackoffRetry;
- import org.apache.zookeeper.CreateMode;
- /**
- *
- * @Description: curator异步创建临时节点
- * @author leeSmall
- * @date 2018年9月2日
- *
- */
- public class CreateNodeAsyncDemo {
- static CountDownLatch cdl = new CountDownLatch(2);
- static ExecutorService es = Executors.newFixedThreadPool(2);
- public static void main(String[] args) throws Exception {
- String path = "/zk-curator";
- CuratorFramework client = CuratorFrameworkFactory.builder().connectString("192.168.152.130:2181")
- .sessionTimeoutMs(5000).retryPolicy(new ExponentialBackoffRetry(1000, 3)).build();
- client.start();
- //创建临时节点
- client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).inBackground(new BackgroundCallback() {
- //回调事件处理
- public void processResult(CuratorFramework client, CuratorEvent event) throws Exception {
- System.out.println("event code: " + event.getResultCode() + ", type: " + event.getType());
- cdl.countDown();
- }
- }, es).forPath(path, "test".getBytes());
- //创建临时节点
- client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).inBackground(new BackgroundCallback() {
- public void processResult(CuratorFramework client, CuratorEvent event) throws Exception {
- System.out.println("event code: " + event.getResultCode() + ", type: " + event.getType());
- cdl.countDown();
- }
- }).forPath(path, "test".getBytes());
- cdl.await();
- es.shutdown();
- }
- }
输出结果:
event code: 0, type: CREATE
event code: -110, type: CREATE
4. curator更新节点数据
- package com.study.demo.curator;
- import org.apache.curator.framework.CuratorFramework;
- import org.apache.curator.framework.CuratorFrameworkFactory;
- import org.apache.curator.retry.ExponentialBackoffRetry;
- import org.apache.zookeeper.CreateMode;
- import org.apache.zookeeper.data.Stat;
- /**
- *
- * @Description: curator更新节点数据
- * @author leeSmall
- * @date 2018年9月2日
- *
- */
- public class UpdateDataDemo {
- public static void main(String[] args) throws Exception {
- String path = "/zk-curator/c1";
- CuratorFramework client = CuratorFrameworkFactory.builder().connectString("192.168.152.130:2181")
- .sessionTimeoutMs(5000).retryPolicy(new ExponentialBackoffRetry(1000, 3)).build();
- client.start();
- client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath(path, "test".getBytes());
- Stat stat = new Stat();
- client.getData().storingStatIn(stat).forPath(path);
- System.out.println("Current data: " + stat.getVersion());
- System.out.println("Update data: "
- + client.setData().withVersion(stat.getVersion()).forPath(path, "some".getBytes()).getVersion());
- }
- }
输出结果:
Current data: 0
Update data: 1
5. curator删除节点数据
- package com.study.demo.curator;
- import org.apache.curator.framework.CuratorFramework;
- import org.apache.curator.framework.CuratorFrameworkFactory;
- import org.apache.curator.retry.ExponentialBackoffRetry;
- import org.apache.zookeeper.CreateMode;
- import org.apache.zookeeper.data.Stat;
- /**
- *
- * @Description: curator删除节点数据
- * @author leeSmall
- * @date 2018年9月2日
- *
- */
- public class DeleteNodeDemo {
- public static void main(String[] args) throws Exception {
- String path = "/zk-curator/c1";
- CuratorFramework client = CuratorFrameworkFactory.builder().connectString("192.168.152.130:2181")
- .sessionTimeoutMs(5000).retryPolicy(new ExponentialBackoffRetry(1000, 3)).build();
- client.start();
- client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath(path, "test".getBytes());
- Stat stat = new Stat();
- client.getData().storingStatIn(stat).forPath(path);
- client.delete().deletingChildrenIfNeeded().withVersion(stat.getVersion()).forPath(path);
- }
- }
6. curator事件监听
- package com.study.demo.curator;
- import org.apache.curator.framework.CuratorFramework;
- import org.apache.curator.framework.CuratorFrameworkFactory;
- import org.apache.curator.framework.recipes.cache.NodeCache;
- import org.apache.curator.framework.recipes.cache.NodeCacheListener;
- import org.apache.curator.retry.ExponentialBackoffRetry;
- import org.apache.zookeeper.CreateMode;
- /**
- *
- * @Description: curator事件监听
- * @author leeSmall
- * @date 2018年9月2日
- *
- */
- public class NodeCacheDemo {
- public static void main(String[] args) throws Exception {
- String path = "/zk-curator/nodecache";
- CuratorFramework client = CuratorFrameworkFactory.builder().connectString("192.168.152.130:2181")
- .sessionTimeoutMs(5000).retryPolicy(new ExponentialBackoffRetry(1000, 3)).build();
- client.start();
- client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath(path, "test".getBytes());
- final NodeCache nc = new NodeCache(client, path, false);
- nc.start();
- //通过回调函数监听事件
- nc.getListenable().addListener(new NodeCacheListener() {
- public void nodeChanged() throws Exception {
- System.out.println("update--current data: " + new String(nc.getCurrentData().getData()));
- }
- });
- client.setData().forPath(path, "test123".getBytes());
- Thread.sleep(1000);
- client.delete().deletingChildrenIfNeeded().forPath(path);
- Thread.sleep(5000);
- nc.close();
- }
- }
输出结果:
update--current data: test123
Curator事件监听:
NodeCache:节点处理监听(会使用缓存)。回调接口NodeCacheListener
PathChildrenCache:子节点缓存,处理子节点变化。回调接口PathChildrenCacheListener
TreeCache:NodeCache和PathChildrenCache的结合体。回调接口TreeCacheListener
四、zookeeper会话
1. zookeeper连接的几种状态
CONNECTING 正在连接
CONNECTED 已经连接
RECONNECTING 正在重新连接
RECONNECTED 重新连接上
CLOSE 会话关闭
2. session
2.1 session主要由几个类控制:
SessionTracker, LearnerSessionTracker, SessionTrackerImpl
session初始化的方法:
org.apache.zookeeper.server.SessionTrackerImpl.initializeNextSession(long)
- public static long initializeNextSession(long id) {
- long nextSid = 0;
- nextSid = (System.currentTimeMillis() << 24) >>> 8;
- nextSid = nextSid | (id <<56);
- return nextSid;
- }
说明:
SessionID的分配(初始化)函数,策略如下:
1)取时间,并且左移24位得到的结果再右移8位(高8位,低16位都是0)
2)sid拿出来进行左移56位
3)和第一步的结果做或运算
2.2 Session分桶(zookeeper的一个特性)
按照Session会话过期时间进行分区块保存。
这样设计的好处:可以快速清理过期的session
2.3 session激活过程:
1)检测会话是否过期
2)计算会话下一次超时时间
3)定位会话的所在区块
4)迁移会话
Zookeeper系列三:Zookeeper客户端的使用(Zookeeper原生API如何进行调用、ZKClient、Curator)和Zookeeper会话的更多相关文章
- ZooKeeper客户端原生API的使用以及ZkClient第三方API的使用
这两部分内容的介绍主要讲的是节点及节点内容和子节点的操作,并且讲解的节点的事件监听以及ACL授权 ZooKeeper客户端原生API的使用 百度网盘地址: http://pan.baidu.com/s ...
- web API简介(三):客户端储存之Web Storage API
概述 前篇:web API简介(二):客户端储存之document.cookie API 客户端储存从某一方面来说和动态网站差不多.动态网站是用服务端来储存数据,而客户端储存是用客户端来储存数据. W ...
- 服务注册中心之ZooKeeper系列(三) 实现分布式锁
通过ZooKeeper的有序节点.节点路径不回重复.还有节点删除会触发Wathcer事件的这些特性,我们可以实现分布式锁. 一.思路 zookeeper中创建一个根节点Locks,用于后续各个客户端的 ...
- Zookeeper系列(二)特征及应用场景
zookeeper类似一个分布式的文件系统,每个节点可以有和它自身或它的子节点相关联的数据,此外指向节点的路劲必须使用绝对路径(不能使用相对路劲): Znode 对应目录树中的的一个节点,并拥有一 ...
- zookeeper原生API做java客户端
简介 本文是使用apache提供的原生api做zookeeper客户端 jar包 zookeeper-3.4.5.jar Demo package bjsxt.zookeeper.base; im ...
- zookeeper系列(三)zookeeper的使用--开源客户端
作者:leesf 掌控之中,才会成功:掌控之外,注定失败, 原创博客地址:http://www.cnblogs.com/leesf456/ 奇文共欣赏,大家共同学习进步. 一.前言 上一篇博客已 ...
- Zookeeper 系列(三)Zookeeper API
Zookeeper 系列(三)Zookeeper API 本节首先介绍 Zookeeper 的 Shell 命令,再对 Java 操作 Zookeeper 的三种方式进行讲解,本节先介绍 Zookee ...
- ZooKeeper系列(三)
前面虽然配置了集群模式的Zookeeper,但是为了方面学建议在伪分布式模式的Zookeeper学习Zookeeper的shell命令. 一.Zookeeper的四字命令 Zookeeper支持某些特 ...
- zookeeper系列(一)zookeeper图形化的客户端工具
追加一个zookeeper图形化的客户端工具: 1.zookeeper图像化客户端工具的下载地址:https://issues.apache.org/jira/secure/attachment/12 ...
随机推荐
- loj#2665. 「NOI2013」树的计数
目录 题目链接 题解 代码 题目链接 loj#2665. 「NOI2013」树的计数 题解 求树高的期望 对bfs序分层 考虑同时符合dfs和bfs序的树满足什么条件 第一个点要强制分层 对于bfs序 ...
- Angular features and services overview
模块(Modules) 组件(Components) 模板(Templates) 元数据(Metadata) 数据绑定(Data binding) 指令(Directives) 服务(Services ...
- jQuery File Upload 判断图片尺寸,限定图片宽高的办法
1.必须熟读jQuery File Upload 文档,在add方法中进行判断,如果不符合条件,就用 data.abort()方法取消上传动作. $("file").fileupl ...
- Java多线程:AQS
在Java多线程:线程间通信之Lock中我们提到了ReentrantLock是API级别的实现,但是没有说明其具体实现原理.实际上,ReentrantLock的底层实现使用了AQS(AbstractQ ...
- Linux下tomcat修改成的80端口无法访问
转自: https://blog.csdn.net/u013252047/article/details/72834415 tomcat放到服务器上访问8080端口还需要输入端口号,造成访问不便,好多 ...
- [web前端] 去哪儿网前端架构师司徒正美:如何挑选适合的前端框架?
原文地址: https://www.jianshu.com/p/6327d4280e3b 最近几年,前端技术迅猛发展,差不多每年都会冒出一款主流的框架. 每次新开业务线或启动新项目时,首先第一件事就是 ...
- android: 在android studio中使用retrolambda的步骤
找了各种说明,包括retrolambda官方文档都没有试成功 最后在这个链接中找到答案:http://blog.csdn.net/qq_26819733/article/details/5222565 ...
- Java代码常见的十种错误
每一个程序员在编写代码的过程中都免不了出现错误或是小的失误,这些小的错误和失误往往使得程序员还得返工.那么,如何才能尽量避免这些错误的发生呢?笔者总结只有在日常的编写代码中总结出经验,在这篇文章中,笔 ...
- Nginx——使用 Nginx 提升网站访问速度【转载+整理】
原文地址 本文是写于 2008 年,文中提到 Nginx 不支持 Windows 操作系统,但是现在它已经支持了,此外还支持 FreeBSD,Solaris,MacOS X~ Nginx(" ...
- volitile关键字
1.volatile关键字的两层语义 一旦一个共享变量(类的成员变量.类的静态成员变量)被volatile修饰之后,那么就具备了两层语义: 1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修 ...