一、Zookeeper-Java-Api原生具有很多不足和使用不便:
1.Zookeeper的watch是一次性的,每次都需要重新注册,不可以循环利用;
2.session的链接超时后没有重连的机制,需要通过代码来实现;
3.异常处理繁琐;
4.原生客户端只提供了简单的字节数组的操作,没有实现序列化,没有针对复杂对象的存储;
5.创建节点过程中如果节点存在就会抛出不友好异常;无法实现多节点递归删除;
二、zkClient改进:
1.session重连机制;
2.提供了部分序列化对象的存储;
3.异常的处理做了封装;
不足:
1.生态不完善,社区不活跃,文档不全;
2.实际异常处理只是抛出RuntimeException,过于简单;
三、Curator:(推荐实际生产)
1.引入依赖:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.curator/curator-framework --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>2.12.0</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.curator/curator-recipes --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>2.12.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
2.代码实现:
package com.cc.springbootzookeepercurator; import lombok.extern.slf4j.Slf4j; import org.apache.curator.RetryPolicy; 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; import java.nio.charset.Charset; @Slf4j public class CuratorTest { /** * 链接字符串(链接集群用逗号隔开):192.168.1.11:2182,192.168.1.11:2183 */ public static final String ZK_HOST = "192.168.1.11:2182,192.168.1.11:2183,192.168.1.11:2184,192.168.1.11:2185"; public static void main(String[] args){ /** * 1.建立连接,方式很多,此处用最简单的方式 */ //创建重连策略:重试5次,每次间隔1秒; RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 5); //创建重连策略:重试5次,每次间隔5秒; //RetryPolicy retryPolicy1 = new RetryNTimes(5,5000); CuratorFramework client = CuratorFrameworkFactory .builder() .connectString(ZK_HOST) .connectionTimeoutMs(5000) .retryPolicy(retryPolicy) //重连策略 .build(); client.start(); log.info(client.getState().name()); //创建节点 createNode(client); //修改节点 //update(client); //删除 //delete(client); client.close(); } /**2.创建节点 * */ public static void createNode(CuratorFramework curatorFramework){ try { //同步创建 curatorFramework.create() .creatingParentsIfNeeded() //节点可以递归创建,如果父节点不存在就创建 .withMode(CreateMode.PERSISTENT) .forPath("/curator/testcora","testcreate".getBytes(Charset.defaultCharset())); //异步创建 //curatorFramework.create().inBackground(); } catch (Exception e) { e.printStackTrace(); } } /**3.设置修改节点内容 * */ public static void update(CuratorFramework curatorFramework){ Stat stat = new Stat(); String path = "/curator/testcora"; try { byte[] data = curatorFramework.getData().storingStatIn(stat).forPath(path); log.info("修改前的值:{}",new String(data,Charset.defaultCharset())); curatorFramework.setData() .withVersion(stat.getVersion()) .forPath(path,"update".getBytes(Charset.defaultCharset())); data = curatorFramework.getData().forPath(path); log.info("修改后的值:{}",new String(data,Charset.defaultCharset())); } catch (Exception e) { e.printStackTrace(); } } /**4.获取子节点 * */ /**5.删除节点 * 可以递归删除 */ public static void delete(CuratorFramework curatorFramework){ String path = "/curator/testcora"; try { curatorFramework.delete() .guaranteed() .deletingChildrenIfNeeded()//递归删除 .withVersion(-1)//删除所以版本 .forPath(path); } catch (Exception e) { e.printStackTrace(); } } /** * zkClient中watch(监听)的使用 */ }
注意:
如果出现以下异常,请降低curator-framework版本
org.apache.zookeeper.KeeperException$ConnectionLossException: KeeperErrorCode = ConnectionLoss for /
org.apache.zookeeper.KeeperException$ConnectionLossException: KeeperErrorCode = ConnectionLoss