Curator客户端
Curator
包含了几个包:curator-framework
:对zookeeper的底层api的一些封装curator-client
:提供一些客户端的操作,例如重试策略等curator-recipes
:封装了一些高级特性,如:Cache事件监听、选举、分布式锁、分布式计数器、分布式Barrier等
- 版本
- The are currently two released versions of Curator, 2.x.x and 3.x.x:
- Curator 2.x.x - compatible with both ZooKeeper 3.4.x and ZooKeeper 3.5.x
- Curator 3.x.x - compatible only with ZooKeeper 3.5.x and includes support for new features such as dynamic reconfiguration, etc.
Curator
主要解决了以下问题- 封装
ZooKeeper client
与ZooKeeper server
之间的连接处理 - 提供了一套
Fluent
风格的操作API - 提供
ZooKeeper
各种应用场景(recipe, 比如共享锁服务, 集群领导选举机制)的抽象封装
- 封装
- 这里使用的版本
- 服务端
Zookeeper
版本:3.4.6
Curator
版本:compile "org.apache.curator:curator-recipes:2.11.0"
- 服务端
创建会话
-
创建会话
@Test public void testCreateClient() throws Exception{ String connectString = "zk-master:2180,zk-slave1:2182,zk-slave2:2183"; int sessionTimeoutMs = 25000; int connectionTimeoutMs = 5000; /** * 失去连接重试策略 * baseSleepTimeMs 初始sleep时间 * maxRetries 最大重试次数 * maxSleepMs 最大sleep时间 * 当前sleep时间=baseSleepTimeMs*Math.mac(1,random.next(1)) << (retryCount+1) */ int baseSleepTimeMs; int maxRetries; int maxSleepMs; RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3); //第一种方式,使用Builder fluent风格的API方式创建 CuratorFramework curatorFramework1 = CuratorFrameworkFactory.builder() .connectString(connectString) .sessionTimeoutMs(sessionTimeoutMs) .connectionTimeoutMs(connectionTimeoutMs) .retryPolicy(retryPolicy) .build(); CuratorFrameworkState state1 = curatorFramework1.getState(); //zk-curator - LATENT logger.info(state1.toString()); //当连接状态变化时触发 curatorFramework1.getConnectionStateListenable().addListener(new ConnectionStateListener() { @Override public void stateChanged(CuratorFramework curatorFramework, ConnectionState connectionState) { //连接状态事件:true logger.info("连接状态事件:{}",connectionState.isConnected()); } }); //完成会话的创建 curatorFramework1.start(); //第二种方式,使用静态工厂方式创建,此方式本质上还是通过第一种方式创建 CuratorFramework curatorFramework2 = CuratorFrameworkFactory.newClient( connectString, sessionTimeoutMs, connectionTimeoutMs, retryPolicy); CuratorFrameworkState state2 = curatorFramework2.getState(); //zk-curator - LATENT logger.info(state2.toString()); /** * 临时客户端: * 一定时间不活动后连接会被关闭,使用buildTemp()创建 */ CuratorTempFramework curatorFramewor3 = CuratorFrameworkFactory.builder() .connectString(connectString) .sessionTimeoutMs(sessionTimeoutMs) .connectionTimeoutMs(connectionTimeoutMs) .retryPolicy(retryPolicy) .buildTemp(2000,TimeUnit.SECONDS); //.buildTemp(); TimeUnit.SECONDS.sleep(20); }
创建节点
-
创建节点
@Test public void testCreateZnode() throws Exception { String connectString = "zk-master:2180,zk-slave1:2182,zk-slave2:2183"; int sessionTimeoutMs = 25000; int connectionTimeoutMs = 5000; String rootPath = "jannal-create"; RetryPolicy retryPolicy = new ExponentialBackoffRetry(4000, 3); CuratorFramework curatorFramework = CuratorFrameworkFactory.builder() .connectString(connectString) .sessionTimeoutMs(sessionTimeoutMs) .connectionTimeoutMs(connectionTimeoutMs) .retryPolicy(retryPolicy) .namespace(rootPath) //客户端对zk上的数据节点的操作都是基本此根节点进行的 .build(); //完成会话创建 curatorFramework.start(); //创建一个初始内容为空的znode,默认创建的是持久节点 curatorFramework.create().forPath("/userEmpty"); //创建一个附带内容的znode curatorFramework.create().forPath("/userData", "我是jannal".getBytes(Charsets.UTF_8)); //创建一个临时节点 curatorFramework.create(). withMode(CreateMode.EPHEMERAL). forPath("/userTemp", "jannal".getBytes(Charsets.UTF_8)); //自动递归创建父节点creatingParentsIfNeeded() curatorFramework.create() .creatingParentsIfNeeded() .withMode(CreateMode.PERSISTENT) .forPath("/user/password", "123456".getBytes(Charsets.UTF_8)); curatorFramework.getCuratorListenable().addListener(new CuratorListener() { @Override public void eventReceived(CuratorFramework curatorFramework, CuratorEvent curatorEvent) throws Exception { } }); ExecutorService executorService = Executors.newFixedThreadPool(2); CountDownLatch countDownLatch = new CountDownLatch(1); /** * 在原生的zookeeper客户端中,所有异步通知事件处理都是通过EventThread这个 * 线程处理的(串行处理所有事件的通知)。一旦发生复杂的处理单元就会消耗很长事件 * 从而影响其他事件的处理,Curator可以使用线程池来处理,如果不指定线程池 * 则默认使用EventThread来处理 */ curatorFramework.create() .creatingParentsIfNeeded() .withMode(CreateMode.EPHEMERAL) .inBackground(new BackgroundCallback() { @Override public void processResult(CuratorFramework client, CuratorEvent event) throws Exception { logger.info(event.toString()); countDownLatch.countDown(); } },executorService) .forPath("/user2","jannal2".getBytes(Charsets.UTF_8)); countDownLatch.await(); executorService.shutdown(); }
获取节点和数据
-
获取节点和数据
@Test public void testGetZnode() throws Exception { String connectString = "zk-master:2180,zk-slave1:2182,zk-slave2:2183"; int sessionTimeoutMs = 25000; int connectionTimeoutMs = 5000; String rootPath = "jannal-get"