一、Zookeeper原生API如何进行调用

准备工作:

首先在新建一个maven项目ZK-Demo,然后在pom.xml里面引入zk的依赖

  1. <dependency>
  2. <groupId>org.apache.zookeeper</groupId>
  3. <artifactId>zookeeper</artifactId>
  4. <version>3.4.10</version>
  5. </dependency>

1. 连接zk并监听事件

  1. package com.study.demo.zk;
  2.  
  3. import java.io.IOException;
  4. import java.util.concurrent.CountDownLatch;
  5.  
  6. import org.apache.zookeeper.WatchedEvent;
  7. import org.apache.zookeeper.Watcher;
  8. import org.apache.zookeeper.Watcher.Event.KeeperState;
  9. import org.apache.zookeeper.ZooKeeper;
  10.  
  11. //连接zk并监听事件
  12. public class ZKDemo implements Watcher {
  13. private static final CountDownLatch cdl = new CountDownLatch(1);
  14.  
  15. public static void main(String[] args) throws IOException {
  16. ZooKeeper zk = new ZooKeeper("192.168.152.130:2181", 5000, new ZKDemo());
  17. System.out.println(zk.getState());
  18.  
  19. try {
  20. cdl.await();
  21. } catch (Exception e) {
  22. System.out.println("ZK Session established.");
  23. }
  24. }
  25.  
  26. //监听到事件时进行处理
  27. public void process(WatchedEvent event) {
  28. System.out.println("Receive watched event:" + event);
  29. if (KeeperState.SyncConnected == event.getState()) {
  30. cdl.countDown();
  31. }
  32. }
  33. }

输出结果:

CONNECTING
Receive watched event:WatchedEvent state:SyncConnected type:None path:null

2. 创建znode并监听事件

  1. package com.study.demo.zk;
  2.  
  3. import java.io.IOException;
  4. import java.util.concurrent.CountDownLatch;
  5.  
  6. import org.apache.zookeeper.CreateMode;
  7. import org.apache.zookeeper.KeeperException;
  8. import org.apache.zookeeper.WatchedEvent;
  9. import org.apache.zookeeper.Watcher;
  10. import org.apache.zookeeper.Watcher.Event.KeeperState;
  11. import org.apache.zookeeper.ZooDefs.Ids;
  12. import org.apache.zookeeper.ZooKeeper;
  13.  
  14. //创建znode并监听事件
  15. public class ZKOperateDemo implements Watcher {
  16. private static final CountDownLatch cdl = new CountDownLatch(1);
  17.  
  18. public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
  19. ZooKeeper zk = new ZooKeeper("192.168.152.130:2181", 5000, new ZKOperateDemo());
  20. cdl.await();
  21.  
  22. String path1 = zk.create("/zk-test-", "123".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
  23. System.out.println("Success create path: " + path1);
  24. String path2 = zk.create("/zk-test-", "456".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
  25. System.out.println("Success create path: " + path2);
  26. }
  27.  
  28. //监听到事件时进行处理
  29. public void process(WatchedEvent event) {
  30. System.out.println("Receive watched event:" + event);
  31. if (KeeperState.SyncConnected == event.getState()) {
  32. cdl.countDown();
  33. }
  34. }
  35. }

输出结果:

Receive watched event:WatchedEvent state:SyncConnected type:None path:null
Success create path: /zk-test-
Success create path: /zk-test-0000000011

3. 改变znode数据并监听事件

  1. package com.study.demo.zk;
  2.  
  3. import java.io.IOException;
  4. import java.util.concurrent.CountDownLatch;
  5.  
  6. import org.apache.zookeeper.CreateMode;
  7. import org.apache.zookeeper.KeeperException;
  8. import org.apache.zookeeper.WatchedEvent;
  9. import org.apache.zookeeper.Watcher;
  10. import org.apache.zookeeper.Watcher.Event.EventType;
  11. import org.apache.zookeeper.Watcher.Event.KeeperState;
  12. import org.apache.zookeeper.ZooDefs.Ids;
  13. import org.apache.zookeeper.ZooKeeper;
  14. import org.apache.zookeeper.data.Stat;
  15.  
  16. //改变znode数据并监听事件
  17. public class ZKDataDemo implements Watcher {
  18. private static final CountDownLatch cdl = new CountDownLatch(1);
  19. private static ZooKeeper zk = null;
  20. private static Stat stat = new Stat();
  21.  
  22. public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
  23. zk = new ZooKeeper("192.168.152.130:2181", 5000, new ZKDataDemo());
  24. cdl.await();
  25.  
  26. zk.create("/zk-test", "123".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
  27. System.out.println(new String(zk.getData("/zk-test", true, stat)));
  28.  
  29. zk.getData("/zk-test", true, stat);
  30. System.out.println(stat.getCzxid() + ", " + stat.getMzxid() + ", " + stat.getVersion());
  31. zk.setData("/zk-test", "123".getBytes(), -1);
  32.  
  33. Thread.sleep(Integer.MAX_VALUE);
  34. }
  35.  
  36. //监听到事件时进行处理
  37. public void process(WatchedEvent event) {
  38. if (KeeperState.SyncConnected == event.getState()) {
  39. if (EventType.None == event.getType() && null == event.getPath()) {
  40. cdl.countDown();
  41. } else if (event.getType() == EventType.NodeDataChanged) {
  42. try {
  43. System.out.println(new String(zk.getData(event.getPath(), true, stat)));
  44. System.out.println(stat.getCzxid() + ", " + stat.getMzxid() + ", " + stat.getVersion());
  45. } catch (Exception e) {
  46. }
  47. }
  48. }
  49. }
  50. }

输出结果:

123
4294967354, 4294967354, 0
123
4294967354, 4294967355, 1

4. 改变子节点并监听事件

  1. package com.study.demo.zk;
  2.  
  3. import java.io.IOException;
  4. import java.util.List;
  5. import java.util.concurrent.CountDownLatch;
  6.  
  7. import org.apache.zookeeper.CreateMode;
  8. import org.apache.zookeeper.KeeperException;
  9. import org.apache.zookeeper.WatchedEvent;
  10. import org.apache.zookeeper.Watcher;
  11. import org.apache.zookeeper.Watcher.Event.EventType;
  12. import org.apache.zookeeper.Watcher.Event.KeeperState;
  13. import org.apache.zookeeper.ZooDefs.Ids;
  14. import org.apache.zookeeper.ZooKeeper;
  15.  
  16. //改变子节点并监听事件
  17. public class ZKChildrenDemo implements Watcher {
  18. private static final CountDownLatch cdl = new CountDownLatch(1);
  19. private static ZooKeeper zk = null;
  20.  
  21. public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
  22. zk = new ZooKeeper("192.168.152.130:2181", 5000, new ZKChildrenDemo());
  23. cdl.await();
  24.  
  25. zk.create("/zk-test", "123".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
  26.  
  27. zk.create("/zk-test/c1", "456".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
  28.  
  29. List<String> list = zk.getChildren("/zk-test", true);
  30. for (String str : list)
  31. System.out.println(str);
  32.  
  33. zk.create("/zk-test/c2", "789".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
  34.  
  35. Thread.sleep(Integer.MAX_VALUE);
  36. }
  37.  
  38. //监听到事件时进行处理
  39. public void process(WatchedEvent event) {
  40. if (KeeperState.SyncConnected == event.getState())
  41. if (EventType.None == event.getType() && null == event.getPath()) {
  42. cdl.countDown();
  43. } else if (event.getType() == EventType.NodeChildrenChanged) {
  44. try {
  45. System.out.println("Child: " + zk.getChildren(event.getPath(), true));
  46. } catch (Exception e) {
  47. }
  48. }
  49. }
  50. }

输出结果:

c1
Child: [c1, c2]

5. 异步调用并完成回调

  1. package com.study.demo.zk;
  2.  
  3. import java.io.IOException;
  4. import java.util.List;
  5. import java.util.concurrent.CountDownLatch;
  6.  
  7. import org.apache.zookeeper.AsyncCallback;
  8. import org.apache.zookeeper.CreateMode;
  9. import org.apache.zookeeper.KeeperException;
  10. import org.apache.zookeeper.WatchedEvent;
  11. import org.apache.zookeeper.Watcher;
  12. import org.apache.zookeeper.Watcher.Event.EventType;
  13. import org.apache.zookeeper.Watcher.Event.KeeperState;
  14. import org.apache.zookeeper.ZooDefs.Ids;
  15. import org.apache.zookeeper.ZooKeeper;
  16. import org.apache.zookeeper.data.Stat;
  17.  
  18. //异步调用并完成回调
  19. class ChildrenCallback implements AsyncCallback.Children2Callback {
  20.  
  21. public void processResult(int rc, String path, Object ctx, List<String> children, Stat stat) {
  22. System.out.println(
  23. "Child: " + rc + ", path: " + path + ", ctx: " + ctx + ", children: " + children + ", stat: " + stat);
  24. }
  25. }
  26.  
  27. public class ZKChildrenAsyncDemo implements Watcher {
  28. private static final CountDownLatch cdl = new CountDownLatch(1);
  29. private static ZooKeeper zk = null;
  30.  
  31. public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
  32. zk = new ZooKeeper("192.168.152.130:2181", 5000, new ZKChildrenAsyncDemo());
  33. cdl.await();
  34.  
  35. zk.create("/zk-test", "123".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
  36.  
  37. zk.create("/zk-test/c1", "456".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
  38.  
  39. zk.getChildren("/zk-test", true, new ChildrenCallback(), "ok");
  40.  
  41. Thread.sleep(Integer.MAX_VALUE);
  42. }
  43.  
  44. //监听到事件时进行处理
  45. public void process(WatchedEvent event) {
  46. if (KeeperState.SyncConnected == event.getState())
  47. if (EventType.None == event.getType() && null == event.getPath()) {
  48. cdl.countDown();
  49. } else if (event.getType() == EventType.NodeChildrenChanged) {
  50. try {
  51. System.out.println("Child: " + zk.getChildren(event.getPath(), true));
  52. } catch (Exception e) {
  53. }
  54. }
  55. }
  56. }

输出结果:

Child: 0, path: /zk-test, ctx: ok, children: [c1], stat: 4294967369,4294967369,1535536716381,1535536716381,0,1,0,0,3,1,4294967370

6. 连接后创建回调

  1. package com.study.demo.zk;
  2.  
  3. import java.io.IOException;
  4. import java.util.concurrent.CountDownLatch;
  5.  
  6. import org.apache.zookeeper.AsyncCallback;
  7. import org.apache.zookeeper.CreateMode;
  8. import org.apache.zookeeper.KeeperException;
  9. import org.apache.zookeeper.WatchedEvent;
  10. import org.apache.zookeeper.Watcher;
  11. import org.apache.zookeeper.Watcher.Event.KeeperState;
  12. import org.apache.zookeeper.ZooDefs.Ids;
  13. import org.apache.zookeeper.ZooKeeper;
  14.  
  15. //连接后创建回调
  16. class IStringCallback implements AsyncCallback.StringCallback {
  17. public void processResult(int rc, String path, Object ctx, String name) {
  18. System.out.println("create path result: [" + rc + ", " + path + "," + ctx + ", real path name: " + name);
  19. }
  20. }
  21.  
  22. public class ZKAsyncDemo implements Watcher {
  23. private static final CountDownLatch cdl = new CountDownLatch(1);
  24.  
  25. public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
  26. ZooKeeper zk = new ZooKeeper("192.168.152.130:2181", 5000, new ZKAsyncDemo());
  27. cdl.await();
  28.  
  29. zk.create("/zk-test-", "123".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL, new IStringCallback(),
  30. new String("I am context"));
  31.  
  32. zk.create("/zk-test-", "456".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL,
  33. new IStringCallback(), new String("I am context"));
  34.  
  35. zk.create("/zk-test-", "789".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL,
  36. new IStringCallback(), new String("I am context"));
  37.  
  38. Thread.sleep(Integer.MAX_VALUE);
  39. }
  40.  
  41. //监听到事件时进行处理
  42. public void process(WatchedEvent event) {
  43. System.out.println("Receive watched event:" + event);
  44. if (KeeperState.SyncConnected == event.getState()) {
  45. cdl.countDown();
  46. }
  47. }
  48. }

输出结果:

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的依赖

  1. <dependency>
  2. <groupId>com.101tec</groupId>
  3. <artifactId>zkclient</artifactId>
  4. <version>0.10</version>
  5. </dependency>

1. ZkClient递归创建顺序节点

  1. package com.study.demo.client;
  2.  
  3. import org.I0Itec.zkclient.ZkClient;
  4.  
  5. /**
  6. *
  7. * @Description: ZkClient递归创建顺序节点
  8. * @author leeSmall
  9. * @date 2018年9月2日
  10. *
  11. */
  12. public class CreateNodeDemo {
  13. public static void main(String[] args) {
  14. ZkClient client = new ZkClient("192.168.152.130:2181", 5000);
  15. String path = "/zk-client/c1";
  16. // 递归创建顺序节点 true:先创建父节点/zk-client
  17. client.createPersistent(path, true);
  18. }
  19. }

创建成功:

2. ZkClient获取数据并监听事件

  1. package com.study.demo.client;
  2.  
  3. import org.I0Itec.zkclient.IZkDataListener;
  4. import org.I0Itec.zkclient.ZkClient;
  5.  
  6. /**
  7. *
  8. * @Description: ZkClient获取数据
  9. * @author leeSmall
  10. * @date 2018年9月2日
  11. *
  12. */
  13. public class GetDataDemo {
  14. public static void main(String[] args) throws InterruptedException {
  15. String path = "/zk-client";
  16. ZkClient client = new ZkClient("192.168.152.130:2181", 5000);
  17. //创建临时节点
  18. client.createEphemeral(path, "123");
  19.  
  20. //注册父节点数据改变的事件
  21. client.subscribeDataChanges(path, new IZkDataListener() {
  22.  
  23. //父节点数据改变事件
  24. public void handleDataChange(String dataPath, Object data) throws Exception {
  25. System.out.println(dataPath + " changed: " + data);
  26. }
  27.  
  28. //父节点数据删除事件
  29. public void handleDataDeleted(String dataPath) throws Exception {
  30. System.out.println(dataPath + " deleted");
  31. }
  32. });
  33.  
  34. System.out.println(client.readData(path).toString());
  35. client.writeData(path, "456");
  36. Thread.sleep(1000);
  37. client.delete(path);
  38. //sleep的目的是为了更好的观察事件变化
  39. Thread.sleep(Integer.MAX_VALUE);
  40. }
  41. }

输出结果:

123
/zk-client changed: 456
/zk-client deleted

3. ZkClient获取子节点数据并监听事件

  1. package com.study.demo.client;
  2.  
  3. import java.util.List;
  4.  
  5. import org.I0Itec.zkclient.IZkChildListener;
  6. import org.I0Itec.zkclient.ZkClient;
  7.  
  8. /**
  9. *
  10. * @Description: ZkClient获取子节点数据
  11. * @author leeSmall
  12. * @date 2018年9月2日
  13. *
  14. */
  15. public class GetChildrenDemo {
  16. public static void main(String[] args) throws InterruptedException {
  17. String path = "/zk-client";
  18. ZkClient client = new ZkClient("192.168.152.130:2181", 5000);
  19. //注册子节点数据改变的事件
  20. client.subscribeChildChanges(path, new IZkChildListener() {
  21.  
  22. //子节点数据改变事件
  23. public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception {
  24. System.out.println(parentPath + "的子发生变化: " + currentChilds);
  25. }
  26. });
  27.  
  28. //创建顺序节点
  29. client.createPersistent(path);
  30. Thread.sleep(1000);
  31. //获取子节点数据 此时还没有创建获取不到
  32. System.out.println(client.getChildren(path));
  33. //在前面的父节点 /zk-client下创建子节点c1
  34. client.createPersistent(path + "/c1");
  35. Thread.sleep(1000);
  36. //删除子节点
  37. client.delete(path + "/c1");
  38. Thread.sleep(1000);
  39. //删除父节点
  40. client.delete(path);
  41. Thread.sleep(Integer.MAX_VALUE);
  42. }
  43. }

输出结果:

/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的依赖

  1. <dependency>
  2. <groupId>org.apache.curator</groupId>
  3. <artifactId>curator-framework</artifactId>
  4. <version>4.0.0</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.apache.curator</groupId>
  8. <artifactId>curator-recipes</artifactId>
  9. <version>4.0.0</version>
  10. </dependency>

1. curator创建连接session

  1. package com.study.demo.curator;
  2.  
  3. import org.apache.curator.RetryPolicy;
  4. import org.apache.curator.framework.CuratorFramework;
  5. import org.apache.curator.framework.CuratorFrameworkFactory;
  6. import org.apache.curator.retry.ExponentialBackoffRetry;
  7.  
  8. /**
  9. *
  10. * @Description: curator创建连接session
  11. * @author leeSmall
  12. * @date 2018年9月2日
  13. *
  14. */
  15. public class CreateSessionDemo {
  16. public static void main(String[] args) throws InterruptedException {
  17. RetryPolicy policy = new ExponentialBackoffRetry(1000, 3);
  18. CuratorFramework client = CuratorFrameworkFactory.builder().connectString("192.168.152.130:2181")
  19. .sessionTimeoutMs(5000).retryPolicy(policy).build();
  20. client.start();
  21. Thread.sleep(Integer.MAX_VALUE);
  22. }
  23. }

这里介绍一种算法:Backoff退避算法

有这样一种场景,有多个请求,如果网络出现阻塞,每1分钟重试一次。
20:25 request1(block)
20:26 request2(block)
20:27 request3(block)
当网络通顺的时候,请求都累在一起来发送
20:28 request4(通顺)request2、3、4
那么前面的请求就没有意义了,所以就有了退避算法,按照指数间隔重试,比如第一次1分钟,第二次2分钟......随着时间的推移,重试间隔越长。

2. curator递归创建顺序节点

  1. package com.study.demo.curator;
  2.  
  3. import org.apache.curator.framework.CuratorFramework;
  4. import org.apache.curator.framework.CuratorFrameworkFactory;
  5. import org.apache.curator.retry.ExponentialBackoffRetry;
  6. import org.apache.zookeeper.CreateMode;
  7.  
  8. /**
  9. *
  10. * @Description: curator递归创建顺序节点
  11. * @author leeSmall
  12. * @date 2018年9月2日
  13. *
  14. */
  15. public class CreateNodeDemo {
  16. public static void main(String[] args) throws Exception {
  17. String path = "/zk-curator/c1";
  18. CuratorFramework client = CuratorFrameworkFactory.builder().connectString("192.168.152.130:2181")
  19. .sessionTimeoutMs(5000).retryPolicy(new ExponentialBackoffRetry(1000, 3)).build();
  20. client.start();
  21. client.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).forPath(path, "test".getBytes());
  22. }
  23. }

创建成功:

3. curator异步创建临时节点

  1. package com.study.demo.curator;
  2.  
  3. import java.util.concurrent.CountDownLatch;
  4. import java.util.concurrent.ExecutorService;
  5. import java.util.concurrent.Executors;
  6.  
  7. import org.apache.curator.framework.CuratorFramework;
  8. import org.apache.curator.framework.CuratorFrameworkFactory;
  9. import org.apache.curator.framework.api.BackgroundCallback;
  10. import org.apache.curator.framework.api.CuratorEvent;
  11. import org.apache.curator.retry.ExponentialBackoffRetry;
  12. import org.apache.zookeeper.CreateMode;
  13.  
  14. /**
  15. *
  16. * @Description: curator异步创建临时节点
  17. * @author leeSmall
  18. * @date 2018年9月2日
  19. *
  20. */
  21. public class CreateNodeAsyncDemo {
  22. static CountDownLatch cdl = new CountDownLatch(2);
  23. static ExecutorService es = Executors.newFixedThreadPool(2);
  24.  
  25. public static void main(String[] args) throws Exception {
  26. String path = "/zk-curator";
  27. CuratorFramework client = CuratorFrameworkFactory.builder().connectString("192.168.152.130:2181")
  28. .sessionTimeoutMs(5000).retryPolicy(new ExponentialBackoffRetry(1000, 3)).build();
  29. client.start();
  30.  
  31. //创建临时节点
  32. client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).inBackground(new BackgroundCallback() {
  33. //回调事件处理
  34. public void processResult(CuratorFramework client, CuratorEvent event) throws Exception {
  35. System.out.println("event code: " + event.getResultCode() + ", type: " + event.getType());
  36. cdl.countDown();
  37. }
  38. }, es).forPath(path, "test".getBytes());
  39.  
  40. //创建临时节点
  41. client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).inBackground(new BackgroundCallback() {
  42.  
  43. public void processResult(CuratorFramework client, CuratorEvent event) throws Exception {
  44. System.out.println("event code: " + event.getResultCode() + ", type: " + event.getType());
  45. cdl.countDown();
  46. }
  47. }).forPath(path, "test".getBytes());
  48.  
  49. cdl.await();
  50. es.shutdown();
  51. }
  52. }

输出结果:

event code: 0, type: CREATE
event code: -110, type: CREATE

4. curator更新节点数据

  1. package com.study.demo.curator;
  2.  
  3. import org.apache.curator.framework.CuratorFramework;
  4. import org.apache.curator.framework.CuratorFrameworkFactory;
  5. import org.apache.curator.retry.ExponentialBackoffRetry;
  6. import org.apache.zookeeper.CreateMode;
  7. import org.apache.zookeeper.data.Stat;
  8.  
  9. /**
  10. *
  11. * @Description: curator更新节点数据
  12. * @author leeSmall
  13. * @date 2018年9月2日
  14. *
  15. */
  16. public class UpdateDataDemo {
  17. public static void main(String[] args) throws Exception {
  18. String path = "/zk-curator/c1";
  19. CuratorFramework client = CuratorFrameworkFactory.builder().connectString("192.168.152.130:2181")
  20. .sessionTimeoutMs(5000).retryPolicy(new ExponentialBackoffRetry(1000, 3)).build();
  21. client.start();
  22. client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath(path, "test".getBytes());
  23. Stat stat = new Stat();
  24. client.getData().storingStatIn(stat).forPath(path);
  25. System.out.println("Current data: " + stat.getVersion());
  26. System.out.println("Update data: "
  27. + client.setData().withVersion(stat.getVersion()).forPath(path, "some".getBytes()).getVersion());
  28. }
  29. }

输出结果:

Current data: 0
Update data: 1

5. curator删除节点数据

  1. package com.study.demo.curator;
  2.  
  3. import org.apache.curator.framework.CuratorFramework;
  4. import org.apache.curator.framework.CuratorFrameworkFactory;
  5. import org.apache.curator.retry.ExponentialBackoffRetry;
  6. import org.apache.zookeeper.CreateMode;
  7. import org.apache.zookeeper.data.Stat;
  8.  
  9. /**
  10. *
  11. * @Description: curator删除节点数据
  12. * @author leeSmall
  13. * @date 2018年9月2日
  14. *
  15. */
  16. public class DeleteNodeDemo {
  17. public static void main(String[] args) throws Exception {
  18. String path = "/zk-curator/c1";
  19. CuratorFramework client = CuratorFrameworkFactory.builder().connectString("192.168.152.130:2181")
  20. .sessionTimeoutMs(5000).retryPolicy(new ExponentialBackoffRetry(1000, 3)).build();
  21. client.start();
  22. client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath(path, "test".getBytes());
  23. Stat stat = new Stat();
  24. client.getData().storingStatIn(stat).forPath(path);
  25. client.delete().deletingChildrenIfNeeded().withVersion(stat.getVersion()).forPath(path);
  26. }
  27. }

6. curator事件监听

  1. package com.study.demo.curator;
  2.  
  3. import org.apache.curator.framework.CuratorFramework;
  4. import org.apache.curator.framework.CuratorFrameworkFactory;
  5. import org.apache.curator.framework.recipes.cache.NodeCache;
  6. import org.apache.curator.framework.recipes.cache.NodeCacheListener;
  7. import org.apache.curator.retry.ExponentialBackoffRetry;
  8. import org.apache.zookeeper.CreateMode;
  9.  
  10. /**
  11. *
  12. * @Description: curator事件监听
  13. * @author leeSmall
  14. * @date 2018年9月2日
  15. *
  16. */
  17. public class NodeCacheDemo {
  18. public static void main(String[] args) throws Exception {
  19. String path = "/zk-curator/nodecache";
  20. CuratorFramework client = CuratorFrameworkFactory.builder().connectString("192.168.152.130:2181")
  21. .sessionTimeoutMs(5000).retryPolicy(new ExponentialBackoffRetry(1000, 3)).build();
  22. client.start();
  23. client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath(path, "test".getBytes());
  24.  
  25. final NodeCache nc = new NodeCache(client, path, false);
  26. nc.start();
  27. //通过回调函数监听事件
  28. nc.getListenable().addListener(new NodeCacheListener() {
  29.  
  30. public void nodeChanged() throws Exception {
  31. System.out.println("update--current data: " + new String(nc.getCurrentData().getData()));
  32. }
  33. });
  34.  
  35. client.setData().forPath(path, "test123".getBytes());
  36. Thread.sleep(1000);
  37. client.delete().deletingChildrenIfNeeded().forPath(path);
  38. Thread.sleep(5000);
  39. nc.close();
  40. }
  41. }

输出结果:

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)

  1. public static long initializeNextSession(long id) {
  2. long nextSid = 0;
  3. nextSid = (System.currentTimeMillis() << 24) >>> 8;
  4. nextSid = nextSid | (id <<56);
  5. return nextSid;
  6. }

说明:

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会话的更多相关文章

  1. ZooKeeper客户端原生API的使用以及ZkClient第三方API的使用

    这两部分内容的介绍主要讲的是节点及节点内容和子节点的操作,并且讲解的节点的事件监听以及ACL授权 ZooKeeper客户端原生API的使用 百度网盘地址: http://pan.baidu.com/s ...

  2. web API简介(三):客户端储存之Web Storage API

    概述 前篇:web API简介(二):客户端储存之document.cookie API 客户端储存从某一方面来说和动态网站差不多.动态网站是用服务端来储存数据,而客户端储存是用客户端来储存数据. W ...

  3. 服务注册中心之ZooKeeper系列(三) 实现分布式锁

    通过ZooKeeper的有序节点.节点路径不回重复.还有节点删除会触发Wathcer事件的这些特性,我们可以实现分布式锁. 一.思路 zookeeper中创建一个根节点Locks,用于后续各个客户端的 ...

  4. Zookeeper系列(二)特征及应用场景

    zookeeper类似一个分布式的文件系统,每个节点可以有和它自身或它的子节点相关联的数据,此外指向节点的路劲必须使用绝对路径(不能使用相对路劲):   Znode 对应目录树中的的一个节点,并拥有一 ...

  5. zookeeper原生API做java客户端

    简介 本文是使用apache提供的原生api做zookeeper客户端 jar包 zookeeper-3.4.5.jar   Demo package bjsxt.zookeeper.base; im ...

  6. zookeeper系列(三)zookeeper的使用--开源客户端

    作者:leesf    掌控之中,才会成功:掌控之外,注定失败, 原创博客地址:http://www.cnblogs.com/leesf456/ 奇文共欣赏,大家共同学习进步. 一.前言 上一篇博客已 ...

  7. Zookeeper 系列(三)Zookeeper API

    Zookeeper 系列(三)Zookeeper API 本节首先介绍 Zookeeper 的 Shell 命令,再对 Java 操作 Zookeeper 的三种方式进行讲解,本节先介绍 Zookee ...

  8. ZooKeeper系列(三)

    前面虽然配置了集群模式的Zookeeper,但是为了方面学建议在伪分布式模式的Zookeeper学习Zookeeper的shell命令. 一.Zookeeper的四字命令 Zookeeper支持某些特 ...

  9. zookeeper系列(一)zookeeper图形化的客户端工具

    追加一个zookeeper图形化的客户端工具: 1.zookeeper图像化客户端工具的下载地址:https://issues.apache.org/jira/secure/attachment/12 ...

随机推荐

  1. loj#2665. 「NOI2013」树的计数

    目录 题目链接 题解 代码 题目链接 loj#2665. 「NOI2013」树的计数 题解 求树高的期望 对bfs序分层 考虑同时符合dfs和bfs序的树满足什么条件 第一个点要强制分层 对于bfs序 ...

  2. Angular features and services overview

    模块(Modules) 组件(Components) 模板(Templates) 元数据(Metadata) 数据绑定(Data binding) 指令(Directives) 服务(Services ...

  3. jQuery File Upload 判断图片尺寸,限定图片宽高的办法

    1.必须熟读jQuery File Upload 文档,在add方法中进行判断,如果不符合条件,就用 data.abort()方法取消上传动作. $("file").fileupl ...

  4. Java多线程:AQS

    在Java多线程:线程间通信之Lock中我们提到了ReentrantLock是API级别的实现,但是没有说明其具体实现原理.实际上,ReentrantLock的底层实现使用了AQS(AbstractQ ...

  5. Linux下tomcat修改成的80端口无法访问

    转自: https://blog.csdn.net/u013252047/article/details/72834415 tomcat放到服务器上访问8080端口还需要输入端口号,造成访问不便,好多 ...

  6. [web前端] 去哪儿网前端架构师司徒正美:如何挑选适合的前端框架?

    原文地址: https://www.jianshu.com/p/6327d4280e3b 最近几年,前端技术迅猛发展,差不多每年都会冒出一款主流的框架. 每次新开业务线或启动新项目时,首先第一件事就是 ...

  7. android: 在android studio中使用retrolambda的步骤

    找了各种说明,包括retrolambda官方文档都没有试成功 最后在这个链接中找到答案:http://blog.csdn.net/qq_26819733/article/details/5222565 ...

  8. Java代码常见的十种错误

    每一个程序员在编写代码的过程中都免不了出现错误或是小的失误,这些小的错误和失误往往使得程序员还得返工.那么,如何才能尽量避免这些错误的发生呢?笔者总结只有在日常的编写代码中总结出经验,在这篇文章中,笔 ...

  9. Nginx——使用 Nginx 提升网站访问速度【转载+整理】

    原文地址 本文是写于 2008 年,文中提到 Nginx 不支持 Windows 操作系统,但是现在它已经支持了,此外还支持 FreeBSD,Solaris,MacOS X~ Nginx(" ...

  10. volitile关键字

    1.volatile关键字的两层语义 一旦一个共享变量(类的成员变量.类的静态成员变量)被volatile修饰之后,那么就具备了两层语义: 1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修 ...