前言
前置条件:已掌握的基本操作,比如在后台可以增减节点、ACL权限设置等。
1.Zookeeper 原生API
1.超时重连,不支持自动,需要手动操作
2.Watch注册一次后会失效
3.不支持递归创建节点
2.Zookeeper API 升级版 Curator
1.解决watcher的注册一次就失效
2.提供更多解决方案并且实现简单
3.提供常用的ZooKeeper工具类
4.编程风格更爽,点点点就可以了
5.可以递归创建节点等
3. 知识点
1.使用curator建立与zk的连接
2.使用curator添加/递归添加节点
3.使用curator删除/递归删除节点
4.使用curator创建/验证 ACL(访问权限列表)
5.使用curator监听 单个/父 节点的变化(watch事件)
6.基于curator实现Zookeeper分布式锁(需要掌握基本的多线程知识)
7.基于curator实现分布式计数器
由于代码量比较大,下文只会涉及到重点代码片段,从而突出重点。
准备工作
1.Maven的pom.xml中配置Zookeeper和Curator的依赖
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<!--建议和本地安装版本保持一致-->
<version>3.7.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>5.2.0</version>
</dependency>
curator-recipes:封装了一些高级特性,如:Cache事件监听、 Elections选举、分布式锁、分布式计数器、分布式Barrier、Queues队列等
一、使用Curator建立与Zookeeper服务连接
该类会被频繁使用,故抽离为一个单独的Utils,里面只存放前后台Connect的代码。
public class ZkConnectCuratorUtil {
final static Logger log = LoggerFactory.getLogger(ZkConnectCuratorUtil.class);
public CuratorFramework zkClient = null; //zk的客户端工具Curator(在本类通过new实例化的是,自动start)
private static final int MAX_RETRY_TIMES = 3; //定义失败重试次数
private static final int BASE_SLEEP_TIME_MS = 5000; //连接失败后,再次重试的间隔时间 单位:毫秒
private static final int SESSION_TIME_OUT = 1000000; //会话存活时间,根据业务灵活指定 单位:毫秒
private static final String ZK_SERVER_IP_PORT = "192.168.31.216:2181";//Zookeeper服务所在的IP和客户端端口
private static final String NAMESPACE = "workspace";//指定后,默认操作的所有的节点都会在该工作空间下进行
//本类通过new ZkCuratorUtil()时,自动连通zkClient
public ZkConnectCuratorUtil() {
RetryPolicy retryPolicy = new RetryNTimes(MAX_RETRY_TIMES, BASE_SLEEP_TIME_MS);//首次连接失败后,重试策略
zkClient = CuratorFrameworkFactory.builder()
//.authorization("digest", "root:root".getBytes())//登录超级管理(需单独配)
.connectString(ZK_SERVER_IP_PORT)
.sessionTimeoutMs(SESSION_TIME_OUT)
.retryPolicy(retryPolicy)
.namespace(NAMESPACE).build();
zkClient.start();
}
public void closeZKClient() {
if (zkClient != null) {
this.zkClient.close();
}
}
public static void main(String[] args) {
ZkConnectCuratorUtil zkUtil=new ZkConnectCuratorUtil();
boolean ifStarted=zkUtil.zkClient.isStarted();
System.out.println("当前客户的状态:" + (ifStarted ? "连接中" : "已关闭"));
zkUtil.closeZKClient();
boolean ifClose = zkUtil.zkClient.isStarted();
System.out.println("当前客户的状态:" + (ifClose ? "连接成功" : "已关闭"));
}
}
下方预告:
增删改查均属前后台交互的操作,故统一写在CuratorDao.java中,统一管理。
各方法第一个入参(CuratorFramework zkClient),使用时通过如下代码获取:
ZkConnectCuratorUtil zkUtil=new ZkConnectCuratorUtil();//new的同时,zk也被启动
CuratorFramework zkClient=zkUtil.zkClient;
注: CuratorFramework相当于ZK原生API中的ZooKeeper类
二、 使用Curator来实现节点的增删改查
1.使用curator(递归)添加节点
//级联创建节点(原生API不支持/后台客户端也不支持,但是Curator支持)
public static void createNodes(CuratorFramework zkClient,String nodePath,String nodeData) throws Exception {
zkClient.create()
.creatingParentContainersIfNeeded()//创建父节点,如果需要的话
.withMode(CreateMode.PERSISTENT) //指定节点是临时的,还是永久的
.withACL(Ids.OPEN_ACL_UNSAFE) //指定节点的操作权限
.forPath(nodePath, nodeData.getBytes());
System.out.println(nodePath+"节点已成功创建…");