zookeeper 客户端

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依赖以及配置

<dependency>
	 <groupId>commons-logging</groupId>
	  <artifactId>commons-logging</artifactId>
	  <version>1.2</version>
</dependency>
<dependency>
	 <groupId>log4j</groupId>
	 <artifactId>log4j</artifactId>
	 <version>1.2.17</version>
</dependency>

 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多次修改节点值,观察控制台结果

/////

猜你喜欢

转载自www.cnblogs.com/godyrg/p/12124934.html