//maven lombok此处不写
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.6.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
</dependency>
//zookeeper,工具类 public class ZkUUtils { private static ZooKeeper zK; private static DefaultWatch defaultWatch = new DefaultWatch(); private static CountDownLatch cc = new CountDownLatch(1); public static ZooKeeper getZk(){ try { zK = new ZooKeeper("1277.0.0.1:2181/testConfig2",3000,defaultWatch); defaultWatch.setCountDownLatch(cc); cc.await(); } catch (Exception e) { e.printStackTrace(); } return zK; } }
//默认监听 @Data public class DefaultWatch implements Watcher { CountDownLatch countDownLatch; @Override public void process(WatchedEvent event) { switch (event.getState()) { case Unknown: break; case Disconnected: break; case NoSyncConnected: break; case SyncConnected: countDownLatch.countDown(); break; case AuthFailed: break; case ConnectedReadOnly: break; case SaslAuthenticated: break; case Expired: break; case Closed: break; } } }
//测试config @Data public class PConfig { private String config; }
//基于zk回调的配置热更 @Data public class PConfigWatchCallBack implements Watcher, AsyncCallback.StatCallback, AsyncCallback.DataCallback { private PConfig pConfig; private ZooKeeper zk; private CountDownLatch cc; @Override public void process(WatchedEvent event) { switch (event.getType()) { case None: break; case NodeCreated: zk.getData("/PTestConfig", this,this,"CCC"); break; case NodeDeleted: pConfig.setConfig(""); cc = new CountDownLatch(1); break; case NodeDataChanged: zk.getData("/PTestConfig", this,this,"CCC"); break; case NodeChildrenChanged: break; case DataWatchRemoved: break; case ChildWatchRemoved: break; case PersistentWatchRemoved: break; } } //StatCallback @Override public void processResult(int rc, String path, Object ctx, Stat stat) { if(Objects.nonNull(stat)){ zk.getData("/PTestConfig", this,this,"CCC"); } } @Override public void processResult(int rc, String path, Object ctx, byte[] data, Stat stat) { String cfg = new String(data); pConfig.setConfig(cfg); cc.countDown(); } public void await(){ zk.exists("/PTestConfig",this,this,"AAA"); try { cc.await(); } catch (InterruptedException e) { e.printStackTrace(); } } }
//测试类 public class PTestConfigMain { private ZooKeeper zk; @Before public void getZk(){ zk = ZkUUtils.getZk(); } @After public void close(){ try { zk.close(); } catch (InterruptedException e) { e.printStackTrace(); } } @Test public void testConfig() throws InterruptedException { PConfigWatchCallBack pConfigWatchCallBack = new PConfigWatchCallBack(); PConfig config = new PConfig(); pConfigWatchCallBack.setPConfig(config); pConfigWatchCallBack.setZk(zk); CountDownLatch countDownLatch = new CountDownLatch(1); pConfigWatchCallBack.setCc(countDownLatch); pConfigWatchCallBack.await(); while(true){ if(config.getConfig().equals("")){ System.out.println("配置被删了"); pConfigWatchCallBack.await(); }else{ System.out.println(config.getConfig()); } TimeUnit.SECONDS.sleep(2); } } }
在zookeeper中创建根节点,/testConfig2
在testConfig2下设定配置,PTestConfig,代码回去读取节点PTestConfig的data,将数据读到config类中,当节点被删除后,测试类中配置提取会阻塞,节点创建或者修改时,会更新
读取到相应的内容