Java代码操作Zookeeper(利用 Apache Curator 库)

[复制链接]
发表于 2024-12-1 16:12:24 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
1. Zookeeper原生客户端库存在的缺点



  • 复杂性高:原生客户端库提供了底层的 API,需要开发者手动处理很多细节,如连接管理、会话管理、非常处理等。这增加了开发的复杂性,容易堕落。
  • 连接管理繁琐:利用原生客户端库时,开发者需要手动管理与 ZooKeeper 的连接。这包罗连接的创建、重连、会话超时处理等。
  • 非常处理复杂:原生客户端库的 API 抛出多种非常,如 KeeperException、InterruptedException 等。开发者需要手动处理这些非常,增加了代码的复杂性。
  • 缺少高级功能:原生客户端库缺少一些高级功能,如连接池管理、自动重试、负载均衡等。这些功能在实际应用中非常有用,但需要开发者本身实现或利用第三方库。
  • 缺少封装和抽象:原生客户端库提供了底层的 API,缺少更高层次的封装和抽象。开发者需要本身编写大量的代码来实现常见的功能,如分布式锁、配置管理等。
  • 性能调优困难:原生客户端库的性能调优需要开发者手动进行,如调解连接超时时间、会话超时时间等。这需要对 ZooKeeper 的工作原理有深入的理解。
  • 缺少社区支持:相比于一些更高级的客户端库(如 Curator),原生客户端库的社区支持相对较少。开发者在利用过程中遇到问题时,可能难以找到办理方案。
2. Apache Curator介绍


2.1 基本概述



  • 界说:Apache Curator是专为Apache ZooKeeper设计的Java/JVM客户端库,通过提供高级API框架及一系列实用工具,大幅低落利用ZooKeeper的复杂度并提升应用的可靠性。
  • 开发背景:Curator最初由Netflix公司开源,目前是Apache的顶级项目。
2.2 焦点功能


  • 高可用性连接管理:自动处理与ZooKeeper服务器的连接断开和重新连接,确保连接的稳固性和可靠性。
  • 易于利用的API:封装复杂的ZooKeeper原语,提供更直观、简洁的利用方式,低落开发难度。
  • 模式(Recipes):预置了一系列常见的分布式盘算模式,如leader选举、分布式锁、缓存机制等,开发者可以快速实现这些分布式体系经典难题。
  • 服务发现与负载均衡:支持动态的服务注册与发现,便于构建云原生应用,进步体系的可扩展性和灵活性。
  • 异步DSL:针对Java 8及以上版本提供了异步编程的支持,进步了相应速度和程序服从。
3. 利用指南

3.1 添加 Maven 依靠

  1. <dependency>
  2.     <groupId>org.apache.curator</groupId>
  3.     <artifactId>curator-framework</artifactId>
  4.     <version>2.12.0</version>
  5. </dependency>
  6. <dependency>
  7.     <groupId>org.apache.curator</groupId>
  8.     <artifactId>curator-recipes</artifactId>
  9.     <version>2.12.0</version>
  10. </dependency>
复制代码
3.2 创建 Curator 客户端

  1. import org.apache.curator.framework.CuratorFramework;
  2. import org.apache.curator.framework.CuratorFrameworkFactory;
  3. import org.apache.curator.retry.ExponentialBackoffRetry;
  4. import org.apache.zookeeper.CreateMode;
  5. public class CuratorExample {
  6.     public static void main(String[] args) throws Exception {
  7.         String connectString = "192.168.200.138:2181";
  8.         String path = "/curator1";
  9.         byte[] data = "myData".getBytes();
  10.         ExponentialBackoffRetry retry = new ExponentialBackoffRetry(5000, 10);
  11.         // 创建 Curator 客户端
  12.         CuratorFramework client = CuratorFrameworkFactory.newClient(connectString, retry);
  13.         // 启动客户端
  14.         client.start();
  15.         // 创建节点
  16.         client.create().withMode(CreateMode.PERSISTENT).forPath(path, data);
  17.         // 获取节点数据
  18.         byte[] retrievedData = client.getData().forPath(path);
  19.         System.out.println("Retrieved data: " + new String(retrievedData));
  20.         // 关闭客户端
  21.         client.close();
  22.     }
  23. }
复制代码
3.3 增编削查操作及Watcher监听

  1. import org.apache.curator.framework.CuratorFramework;
  2. import org.apache.curator.framework.CuratorFrameworkFactory;
  3. import org.apache.curator.framework.api.CuratorEvent;
  4. import org.apache.curator.retry.ExponentialBackoffRetry;
  5. import org.apache.zookeeper.CreateMode;
  6. import org.apache.zookeeper.WatchedEvent;
  7. import org.apache.zookeeper.Watcher;
  8. public class CuratorExample {
  9.     public static void main(String[] args) throws Exception {
  10.         String connectString = "192.168.200.138:2181";
  11.         String path = "/curator1";
  12.         byte[] data1 = "myData1".getBytes();
  13.         byte[] data2 = "myData2".getBytes();
  14.         ExponentialBackoffRetry retry = new ExponentialBackoffRetry(5000, 10);
  15.         // 创建 Curator 客户端
  16.         CuratorFramework client = CuratorFrameworkFactory.newClient(connectString, retry);
  17.         // 启动客户端
  18.         client.start();
  19.         // 增加临时监听操作
  20.         client.getCuratorListenable().addListener((CuratorFramework c, CuratorEvent event) -> {
  21.             switch (event.getType()) {
  22.                 case WATCHED:
  23.                     WatchedEvent watchedEvent = event.getWatchedEvent();
  24.                     if (watchedEvent.getType() == Watcher.Event.EventType.NodeDataChanged) {
  25.                         System.out.println("监听的数据变化为: " + new String(c.getData().forPath(path)));
  26.                         System.out.println("触发事件");
  27.                     }
  28.             }
  29.         });
  30.         // 创建节点
  31.         client.create().withMode(CreateMode.PERSISTENT).forPath(path, data1);
  32.         // 获取节点数据
  33.         byte[] retrievedData = client.getData().watched().forPath(path);
  34.         System.out.println("原始数据: " + new String(retrievedData));
  35.         // 修改节点数据
  36.         client.setData().forPath(path, data2);
  37.         Thread.sleep(2000);
  38.         // 删除节点
  39.         client.delete().forPath(path);
  40.         Thread.sleep(2000);
  41.     }
  42. }
复制代码
3.4 进行永世监听

  1. import org.apache.curator.framework.CuratorFramework;
  2. import org.apache.curator.framework.CuratorFrameworkFactory;
  3. import org.apache.curator.framework.recipes.cache.ChildData;
  4. import org.apache.curator.framework.recipes.cache.NodeCache;
  5. import org.apache.curator.retry.ExponentialBackoffRetry;
  6. import org.apache.zookeeper.CreateMode;
  7. public class PermanentWatcherExample {
  8.     public static void main(String[] args) throws Exception {
  9.         String connectString = "192.168.200.138:2181";
  10.         String path = "/curator1";
  11.         byte[] data1 = "myData1".getBytes();
  12.         byte[] data2 = "myData2".getBytes();
  13.         byte[] data3 = "myData3".getBytes();
  14.         ExponentialBackoffRetry retry = new ExponentialBackoffRetry(5000, 10);
  15.         // 创建 Curator 客户端
  16.         CuratorFramework client = CuratorFrameworkFactory.newClient(connectString, retry);
  17.         // 启动客户端
  18.         client.start();
  19.         // 永久监听
  20.         client.create().withMode(CreateMode.PERSISTENT).forPath(path, data1);
  21.         NodeCache nodeCache = new NodeCache(client, path);
  22.         nodeCache.start();
  23.         nodeCache.getListenable().addListener(() -> {
  24.             ChildData currentData = nodeCache.getCurrentData();
  25.             if (currentData != null) {
  26.                 System.out.println("触发了永久监听的回调,当前值为:" + new String(currentData.getData()));
  27.             }
  28.         });
  29.         client.setData().forPath(path, data1);
  30.         Thread.sleep(2000);
  31.         client.setData().forPath(path, data2);
  32.         Thread.sleep(2000);
  33.         client.setData().forPath(path, data3);
  34.         Thread.sleep(2000);
  35.         client.delete().forPath(path);
  36.     }
  37. }
复制代码
3.5 利用分布式锁

  1. import org.apache.curator.framework.CuratorFramework;
  2. import org.apache.curator.framework.CuratorFrameworkFactory;
  3. import org.apache.curator.framework.recipes.locks.InterProcessMutex;
  4. import org.apache.curator.retry.ExponentialBackoffRetry;
  5. public class DistributedLockExample {
  6.     public static void main(String[] args) throws Exception {
  7.         String connectString = "192.168.200.138:2181";
  8.         String path = "/myLock";
  9.         ExponentialBackoffRetry retry = new ExponentialBackoffRetry(5000, 10);
  10.         // 创建 Curator 客户端
  11.         CuratorFramework client = CuratorFrameworkFactory.newClient(connectString, retry);
  12.         // 启动客户端
  13.         client.start();
  14.         // 创建分布式锁
  15.         InterProcessMutex lock = new InterProcessMutex(client, path);
  16.         // 获取锁
  17.         lock.acquire();
  18.         try {
  19.             // 执行临界区代码
  20.             System.out.println("Lock acquired, executing critical section...");
  21.             Thread.sleep(2000);
  22.         } finally {
  23.             // 释放锁
  24.             lock.release();
  25.             System.out.println("Lock released.");
  26.         }
  27.         // 关闭客户端
  28.         client.close();
  29.     }
  30. }
复制代码
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表