第7章 Apache Curator客户端的使用

7-1 curator简介与客户端之间的异同点

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


7-2 搭建maven工程,建立curator与zkserver的连接

这个是需要引入的依赖:

		<dependency>
			<groupId>org.apache.curator</groupId>
			<artifactId>curator-framework</artifactId>
			<version>4.0.0</version>
		</dependency>

		<dependency>
			<groupId>org.apache.curator</groupId>
			<artifactId>curator-recipes</artifactId>
			<version>4.0.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.zookeeper</groupId>
			<artifactId>zookeeper</artifactId>
			<version>3.4.11</version>
		</dependency>

前面两种是比较推荐的:
当构建好了RetryPolicy对象了之后,就可以用建造者模式来进行构建客户端:

public class CuratorOperator {

	public CuratorFramework client = null;
	public static final String zkServerPath = "192.168.1.110:2181";

	/**
	 * 实例化zk客户端
	 */
	public CuratorOperator() {
		/**
		 * 同步创建zk示例,原生api是异步的
		 * 
		 * curator链接zookeeper的策略:ExponentialBackoffRetry
		 * baseSleepTimeMs:初始sleep的时间
		 * maxRetries:最大重试次数
		 * maxSleepMs:最大重试时间
		 */
//		RetryPolicy 	retryPolicy = new ExponentialBackoffRetry(1000, 5);
		
		/**
		 * curator链接zookeeper的策略:RetryNTimes
		 * n:重试的次数
		 * sleepMsBetweenRetries:每次重试间隔的时间
		 */
		RetryPolicy retryPolicy = new RetryNTimes(3, 5000);
		
		/**
		 * curator链接zookeeper的策略:RetryOneTime
		 * sleepMsBetweenRetry:每次重试间隔的时间
		 */
//		RetryPolicy retryPolicy2 = new RetryOneTime(3000);
		
		/**
		 * 永远重试,不推荐使用
		 */
//		RetryPolicy retryPolicy3 = new RetryForever(retryIntervalMs)
		
		/**
		 * curator链接zookeeper的策略:RetryUntilElapsed
		 * maxElapsedTimeMs:最大重试时间
		 * sleepMsBetweenRetries:每次重试间隔
		 * 重试时间超过maxElapsedTimeMs后,就不再重试
		 */
//		RetryPolicy retryPolicy4 = new RetryUntilElapsed(2000, 3000);
		
		client = CuratorFrameworkFactory.builder()
				.connectString(zkServerPath)
				.sessionTimeoutMs(10000).retryPolicy(retryPolicy)
				.namespace("workspace").build();
		client.start();
	}
	
	/**
	 * 
	 * @Description: 关闭zk客户端连接
	 */
	public void closeZKClient() {
		if (client != null) {
			this.client.close();
		}
	}
	
	public static void main(String[] args) throws Exception {
		// 实例化
		CuratorOperator cto = new CuratorOperator();
		boolean isZkCuratorStarted = cto.client.isStarted();
		System.out.println("当前客户的状态:" + (isZkCuratorStarted ? "连接中" : "已关闭"));
		
		// 创建节点
		String nodePath = "/super/imooc";
//		byte[] data = "superme".getBytes();
//		cto.client.create().creatingParentsIfNeeded()
//			.withMode(CreateMode.PERSISTENT)
//			.withACL(Ids.OPEN_ACL_UNSAFE)
//			.forPath(nodePath, data);
		
		// 更新节点数据
//		byte[] newData = "batman".getBytes();
//		cto.client.setData().withVersion(0).forPath(nodePath, newData);
		
		// 删除节点
//		cto.client.delete()
//				  .guaranteed()					// 如果删除失败,那么在后端还是继续会删除,直到成功
//				  .deletingChildrenIfNeeded()	// 如果有子节点,就删除
//				  .withVersion(0)
//				  .forPath(nodePath);
		
		
		
		// 读取节点数据
//		Stat stat = new Stat();
//		byte[] data = cto.client.getData().storingStatIn(stat).forPath(nodePath);
//		System.out.println("节点" + nodePath + "的数据为: " + new String(data));
//		System.out.println("该节点的版本号为: " + stat.getVersion());
		
		
		// 查询子节点
//		List<String> childNodes = cto.client.getChildren()
//											.forPath(nodePath);
//		System.out.println("开始打印子节点:");
//		for (String s : childNodes) {
//			System.out.println(s);
//		}
		
				
		// 判断节点是否存在,如果不存在则为空
//		Stat statExist = cto.client.checkExists().forPath(nodePath + "/abc");
//		System.out.println(statExist);
		
		
		// watcher 事件  当使用usingWatcher的时候,监听只会触发一次,监听完毕后就销毁
//		cto.client.getData().usingWatcher(new MyCuratorWatcher()).forPath(nodePath);
//		cto.client.getData().usingWatcher(new MyWatcher()).forPath(nodePath);
		
		// 为节点添加watcher
		// NodeCache: 监听数据节点的变更,会触发事件
//		final NodeCache nodeCache = new NodeCache(cto.client, nodePath);
//		// buildInitial : 初始化的时候获取node的值并且缓存
//		nodeCache.start(true);
//		if (nodeCache.getCurrentData() != null) {
//			System.out.println("节点初始化数据为:" + new String(nodeCache.getCurrentData().getData()));
//		} else {
//			System.out.println("节点初始化数据为空...");
//		}
//		nodeCache.getListenable().addListener(new NodeCacheListener() {
//			public void nodeChanged() throws Exception {
//				if (nodeCache.getCurrentData() == null) {
//					System.out.println("空");
//					return;
//				}
//				String data = new String(nodeCache.getCurrentData().getData());
//				System.out.println("节点路径:" + nodeCache.getCurrentData().getPath() + "数据:" + data);
//			}
//		});
		
		
		// 为子节点添加watcher
		// PathChildrenCache: 监听数据节点的增删改,会触发事件
		String childNodePathCache =  nodePath;
		// cacheData: 设置缓存节点的数据状态
		final PathChildrenCache childrenCache = new PathChildrenCache(cto.client, childNodePathCache, true);
		/**
		 * StartMode: 初始化方式
		 * POST_INITIALIZED_EVENT:异步初始化,初始化之后会触发事件
		 * NORMAL:异步初始化
		 * BUILD_INITIAL_CACHE:同步初始化
		 */
		childrenCache.start(StartMode.POST_INITIALIZED_EVENT);
		
		List<ChildData> childDataList = childrenCache.getCurrentData();
		System.out.println("当前数据节点的子节点数据列表:");
		for (ChildData cd : childDataList) {
			String childData = new String(cd.getData());
			System.out.println(childData);
		}
		
		childrenCache.getListenable().addListener(new PathChildrenCacheListener() {
			public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
				if(event.getType().equals(PathChildrenCacheEvent.Type.INITIALIZED)){
					System.out.println("子节点初始化ok...");
				}
				
				else if(event.getType().equals(PathChildrenCacheEvent.Type.CHILD_ADDED)){
					String path = event.getData().getPath();
					if (path.equals(ADD_PATH)) {
						System.out.println("添加子节点:" + event.getData().getPath());
						System.out.println("子节点数据:" + new String(event.getData().getData()));
					} else if (path.equals("/super/imooc/e")) {
						System.out.println("添加不正确...");
					}
					
				}else if(event.getType().equals(PathChildrenCacheEvent.Type.CHILD_REMOVED)){
					System.out.println("删除子节点:" + event.getData().getPath());
				}else if(event.getType().equals(PathChildrenCacheEvent.Type.CHILD_UPDATED)){
					System.out.println("修改子节点路径:" + event.getData().getPath());
					System.out.println("修改子节点数据:" + new String(event.getData().getData()));
				}
			}
		});
		
		Thread.sleep(100000);
		
		cto.closeZKClient();
		boolean isZkCuratorStarted2 = cto.client.isStarted();
		System.out.println("当前客户的状态:" + (isZkCuratorStarted2 ? "连接中" : "已关闭"));
	}
	
	public final static String ADD_PATH = "/super/imooc/d";
	
}

7-3 zk命名空间以及创建节点

	public static void main(String[] args) throws Exception {
		// 实例化
		CuratorOperator cto = new CuratorOperator();
		boolean isZkCuratorStarted = cto.client.isStarted();
		System.out.println("当前客户的状态:" + (isZkCuratorStarted ? "连接中" : "已关闭"));
		// 创建节点
		String nodePath = "/super/ldc";
		byte[] data = "superme".getBytes();
		cto.client.create().creatingParentsIfNeeded()
			.withMode(CreateMode.PERSISTENT)
			.withACL(Ids.OPEN_ACL_UNSAFE)
			.forPath(nodePath, data);
	}		

7-9 zk-watcher实例 统一更新N台节点的配置文件

在这里插入图片描述
有3个客户端类:

public class Client1 {

	public CuratorFramework client = null;
	public static final String zkServerPath = "192.168.1.110:2181";

	public Client1() {
		RetryPolicy retryPolicy = new RetryNTimes(3, 5000);
		client = CuratorFrameworkFactory.builder()
				.connectString(zkServerPath)
				.sessionTimeoutMs(10000).retryPolicy(retryPolicy)
				.namespace("workspace").build();
		client.start();
	}
	
	public void closeZKClient() {
		if (client != null) {
			this.client.close();
		}
	}
	
//	public final static String CONFIG_NODE = "/super/imooc/redis-config";
	public final static String CONFIG_NODE_PATH = "/super/imooc";
	public final static String SUB_PATH = "/redis-config";
	public static CountDownLatch countDown = new CountDownLatch(1);
	
	public static void main(String[] args) throws Exception {
		Client1 cto = new Client1();
		System.out.println("client1 启动成功...");
		
		final PathChildrenCache childrenCache = new PathChildrenCache(cto.client, CONFIG_NODE_PATH, true);
		childrenCache.start(StartMode.BUILD_INITIAL_CACHE);
		
		// 添加监听事件
		childrenCache.getListenable().addListener(new PathChildrenCacheListener() {
			public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
				// 监听节点变化
				if(event.getType().equals(PathChildrenCacheEvent.Type.CHILD_UPDATED)){
					String configNodePath = event.getData().getPath();
					if (configNodePath.equals(CONFIG_NODE_PATH + SUB_PATH)) {
						System.out.println("监听到配置发生变化,节点路径为:" + configNodePath);
						
						// 读取节点数据
						String jsonConfig = new String(event.getData().getData());
						System.out.println("节点" + CONFIG_NODE_PATH + "的数据为: " + jsonConfig);
						
						// 从json转换配置
						RedisConfig redisConfig = null;
						if (StringUtils.isNotBlank(jsonConfig)) {
							redisConfig = JsonUtils.jsonToPojo(jsonConfig, RedisConfig.class);
						}
						
						// 配置不为空则进行相应操作
						if (redisConfig != null) {
							String type = redisConfig.getType();
							String url = redisConfig.getUrl();
							String remark = redisConfig.getRemark();
							// 判断事件
							if (type.equals("add")) {
								System.out.println("监听到新增的配置,准备下载...");
								// ... 连接ftp服务器,根据url找到相应的配置
								Thread.sleep(500);
								System.out.println("开始下载新的配置文件,下载路径为<" + url + ">");
								// ... 下载配置到你指定的目录
								Thread.sleep(1000);
								System.out.println("下载成功,已经添加到项目中");
								// ... 拷贝文件到项目目录
							} else if (type.equals("update")) {
								System.out.println("监听到更新的配置,准备下载...");
								// ... 连接ftp服务器,根据url找到相应的配置
								Thread.sleep(500);
								System.out.println("开始下载配置文件,下载路径为<" + url + ">");
								// ... 下载配置到你指定的目录
								Thread.sleep(1000);
								System.out.println("下载成功...");
								System.out.println("删除项目中原配置文件...");
								Thread.sleep(100);
								// ... 删除原文件
								System.out.println("拷贝配置文件到项目目录...");
								// ... 拷贝文件到项目目录
							} else if (type.equals("delete")) {
								System.out.println("监听到需要删除配置");
								System.out.println("删除项目中原配置文件...");
							}
							
							// TODO 视情况统一重启服务
						}
					}
				}
			}
		});
		
		countDown.await();
		
		cto.closeZKClient();
	}
	
}

7-10 curator之acl权限操作与认证授权

public class CuratorAcl {

	public CuratorFramework client = null;
	public static final String zkServerPath = "192.168.1.110:2181";

	public CuratorAcl() {
		RetryPolicy retryPolicy = new RetryNTimes(3, 5000);
		client = CuratorFrameworkFactory.builder().authorization("digest", "imooc1:123456".getBytes())
				.connectString(zkServerPath)
				.sessionTimeoutMs(10000).retryPolicy(retryPolicy)
				.namespace("workspace").build();
		client.start();
	}
	
	public void closeZKClient() {
		if (client != null) {
			this.client.close();
		}
	}
	
	public static void main(String[] args) throws Exception {
		// 实例化
		CuratorAcl cto = new CuratorAcl();
		boolean isZkCuratorStarted = cto.client.isStarted();
		System.out.println("当前客户的状态:" + (isZkCuratorStarted ? "连接中" : "已关闭"));
		
		String nodePath = "/acl/father/child/sub";
		
		List<ACL> acls = new ArrayList<ACL>();
		Id imooc1 = new Id("digest", AclUtils.getDigestUserPwd("imooc1:123456"));
		Id imooc2 = new Id("digest", AclUtils.getDigestUserPwd("imooc2:123456"));
		acls.add(new ACL(Perms.ALL, imooc1));
		acls.add(new ACL(Perms.READ, imooc2));
		acls.add(new ACL(Perms.DELETE | Perms.CREATE, imooc2));
		
		// 创建节点
//		byte[] data = "spiderman".getBytes();
//		cto.client.create().creatingParentsIfNeeded()
//				.withMode(CreateMode.PERSISTENT)
//				.withACL(acls, true)
//				.forPath(nodePath, data);
		

		cto.client.setACL().withACL(acls).forPath("/curatorNode");
		
		// 更新节点数据
//		byte[] newData = "batman".getBytes();
//		cto.client.setData().withVersion(0).forPath(nodePath, newData);
		
		// 删除节点
//		cto.client.delete().guaranteed().deletingChildrenIfNeeded().withVersion(0).forPath(nodePath);
		
		// 读取节点数据
//		Stat stat = new Stat();
//		byte[] data = cto.client.getData().storingStatIn(stat).forPath(nodePath);
//		System.out.println("节点" + nodePath + "的数据为: " + new String(data));
//		System.out.println("该节点的版本号为: " + stat.getVersion());
		
		
		cto.closeZKClient();
		boolean isZkCuratorStarted2 = cto.client.isStarted();
		System.out.println("当前客户的状态:" + (isZkCuratorStarted2 ? "连接中" : "已关闭"));
	}
	
}

猜你喜欢

转载自blog.csdn.net/weixin_37778801/article/details/84704262