1.新建maven工程
2.导入依赖包
<dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.10</version> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.9</version> </dependency>
3.新建测试类ZkTest
4.在zookeeper服务器设置一个测试节点
5.在测试类中编写以下代码:
/** * */ package com.yrg.zk.test; import java.io.IOException; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.data.Stat; import org.junit.Test; /** * @author yangrg * @date 2019年12月31日 下午2:29:27 */ public class ZkTest { private ZooKeeper zooKeeper; { String connectString = "127.0.0.1:2181";//连接的zookeeper服务器 int sessionTimeout = 5000; Watcher watcher = new Watcher() { public void process(WatchedEvent event) { // TODO Auto-generated method stub } }; try { zooKeeper = new ZooKeeper(connectString, sessionTimeout, watcher); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Test public void testUpdateNodeData() throws KeeperException, InterruptedException { String path = "/animal/cat";//要操作的节点路径 byte[] data = zooKeeper.getData(path, false, new Stat());//从zookeeper获取当前节点数据,将watcher设为false,不需要监听 String result = new String(data);//将字节数组转为字符串 System.out.println(result);//打印结果 byte[] newValue = new String("mimi").getBytes();//设置节点数据新值的字节数组 int version = 0;//当前操作zookeeper节点数据的版本号,如果不确定可以使用-1,忽略版本号 Stat stat = zooKeeper.setData("/animal/cat", newValue, version);//修改zookeeper节点数据,返回stat int newVersion = stat.getVersion();//获取节点版本号 System.out.println(newVersion);//打印结果 data = zooKeeper.getData(path, false, new Stat());//重新从zookeeper获取修改后的节点数据 result = new String(data);//将字节数组转为字符串 System.out.println(result);//打印结果 } }
6.测试结果
二,异步通知机制
(1)一次通知
1.导入log4j配置
log4j.properties
# Global logging configuration #开发环境日志要设成DEBUG,生产环境设成info或error #log4j.rootLogger=ERROR, stdout log4j.rootLogger=DEBUG, stdout # MyBatis logging configuration... log4j.logger.org.mybatis.example.BlogMapper=TRACE # Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
2.在刚才的测试类中添加如下方法
@Test public void testNoticeOnce() throws KeeperException, InterruptedException { //一次通知 String path = "/animal/cat"; Watcher watch = new Watcher() { //当前Watcher检测到节点值修改,会调用这个processor()方法 public void process(WatchedEvent event) { // TODO Auto-generated method stub System.out.println("接收到了通知!发生了修改"); } }; byte[] oldData = zooKeeper.getData(path, watch,new Stat()); System.out.println("old Data="+ new String(oldData)); while(true) { Thread.sleep(5000); System.err.println("当前方法要执行的业务逻辑"); } }
运行此方法,在zookeeper修改节点值,观察控制台结果
(2)持续性通知
1.在刚才的测试类中添加如下方法
@Test public void testNoticeForever() throws KeeperException, InterruptedException { String path = "/animal/cat"; getDataWithNotice(zooKeeper, path); while(true) { Thread.sleep(5000); System.err.println("当前方法要执行的业务逻辑 线程名称:"+Thread.currentThread().getName()); } } public void getDataWithNotice(final ZooKeeper zooKeeper,final String path) throws KeeperException, InterruptedException { byte[] data = zooKeeper.getData(path, new Watcher() { //以类似递归的方式调用getDataWithNotice()方法实现持续调用 public void process(WatchedEvent event) { // TODO Auto-generated method stub try { getDataWithNotice(zooKeeper, path);
System.err.println("通知 线程名称:"+Thread.currentThread().getName()); } catch (KeeperException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } },new Stat()); String result = new String(data); System.err.println("当前节点值为="+result); }
运行此方法,在zookeeper多次修改节点值,观察控制台结果
/////