Zookeeper(传统客户端,zkClient,Curator)三种客户端连接操作

Zookeeper传统客户端

新建maven工程

加入依赖

<dependencies>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.8</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.8.2</version>
        </dependency>
    </dependencies>

1. 创建会话

2. 创建节点

3. 读取数据

4. 更新数据

5. 检测节点是否存在

  public Stat / void exists(final String path, Watcher watcher, StatCallback cb, Object ctx)

6.  watch监听

  org.apache.zookeeper.WatcherKeeperStateEventType

(1)没有专门的API去注册watcher,依附于增删改查API;

  (2) watch是一次性产品

  (3) watchprocess方法中,可对不同事件进行处理;

 

/**
 * 创建连接
 */
public class CreateSession {
	
	private final static String CONNECTIONSTR="192.168.25.200:2181";
	private static CountDownLatch countDownLatch= new CountDownLatch(1);
	public static void main(String[] args) throws Exception {
		//创建zk 连接地址,超时时间,监听
		ZooKeeper zooKeeper = new ZooKeeper(CONNECTIONSTR,5000,new Watcher() {
			public void process(WatchedEvent watchedEvent) {
				//如果已经连接了才继续执行创建等其他操作
				if(watchedEvent.getState()==Event.KeeperState.SyncConnected){
					countDownLatch.countDown();
					if(watchedEvent.getType() == EventType.NodeDataChanged){
						//如果节点发生了变化
						System.out.println("节点发生了变化,路径:"+watchedEvent.getPath());
					}
				}
			}
		});
		//确定连接再操作	阻塞
		countDownLatch.await();
		System.out.println(zooKeeper.getState());
		//创建节点,节点路径,节点值,ACL权限,节点类型(持久or临时)
//		zooKeeper.create("/testnode1","xuxu".getBytes(),
//				ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
		
		//获取节点数据	watch=true  stat是状态信息
		Stat stat = new Stat();
		byte[] data = zooKeeper.getData("/testnode1", true, stat);
		System.out.println(new String(data));
		
		//修改数据 (这里的-1代表不进行版本控制)
		zooKeeper.setData("/testnode1", "xuxuupdate1".getBytes(),-1);
//		byte[] dataUpdate = zooKeeper.getData("/testnode1", true, stat);
//		System.out.println(new String(dataUpdate));
		
		//删除节点
//		zooKeeper.delete("/testnode1", -1);
		
		//获取节点下所有子节点
//		List<String> children = zooKeeper.getChildren("/testnode1", true);
//		System.out.println(children);
	}
}

Zookeeper原生客户端在开发支持上的弊端

1. 会话的连接是异步的 如果创建了连接需要监听连接上之后才能进行后续操作; ·

2. Watch需要重复注册 watch是一次性的,比如修改后,如果不使用byte[] data = zooKeeper.getData("/testnode1", true, stat)无法监听到节点是否变化;· 

3. Session重连机制;

4. 开发复杂性较高 比如要实现递归创建节点,或者级联删除就很麻烦;


zkClient

pom文件

<dependencies>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.8</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.8.2</version>
        </dependency>
        <dependency>
			<groupId>com.101tec</groupId>
			<artifactId>zkclient</artifactId>
			<version>0.10</version>
		</dependency>
    </dependencies>

1. 创建会话(同步,重试)

public ZkClient(final String zkServers, final int sessionTimeout,

                final int connectionTimeout, final ZkSerializer zkSerializer,

                final long operationRetryTimeout)

2. 创建节点(同步,递归创建)

public String create(String path,Object data,final List<ACL> acl,CreateMode mode)

public void createPersistent(String path,boolean createParents,List<ACL> acl)

public void createPersistent(String path, Object data, List<ACL> acl)

public String createPersistentSequential(String path,Object data,List<ACL> acl)

public void createEphemeral(String path, Object data, List<ACL> acl)

public String createEphemeralSequential(String path,Object data,List<ACL> acl)

3. 删除节点(同步,递归删除)

public boolean delete(String path,int version)

public boolean deleteRecursive(String path)

4.获取节点(同步,避免不存在异常)

public List<String> getChildren(String path)

public <T> T readData(String path, boolean returnNullIfPathNotExists)

public <T> T readData(String path, Stat stat)

5. 更新节点(同步,实现CAS,状态返回)

public void writeData(String path, Object datat, int expectedVersion)

public Stat writeDataReturnStat(String path,Object datat,int expectedVersion)

6. 检测节点存在(同步)

public boolean exists(String path)

7.权限控制(同步)

public void addAuthInfo(String scheme, final byte[] auth);

public void setAcl(final String path, final List<ACL> acl);

8. 监听器

package com.xuxu;

import java.util.concurrent.TimeUnit;
import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;

/**
 * 使用zkClient
 */
public class ZkClientTest {
	private final static String CONNECTIONSTR="192.168.25.200:2181";
	public static void main(String[] args) {
		//zk服务器地址,超时时间
		ZkClient client = new ZkClient(CONNECTIONSTR,5000);
		System.out.println(client+"--success");
		
		//创建节点 路径,数据,数据类型(持久化节点)
//		client.create("/zknodetest2", "111",CreateMode.PERSISTENT);
		
		//持续递归创建节点	boolean createParents:true 是否创建父节点
//		client.createPersistent("/zknodetest3/test1/test2", true);
		
		//获取单个节点
//		String data =client.readData("/zknodetest2");
//		System.out.println(data);
		
		//获取所有子节点
//		List<String> children = client.getChildren("/zknodetest3");
//		System.out.println(children);
		
		//删除单个子节点
//		boolean delete = client.delete("/zknodetest2");
//		System.out.println(delete);
		
		//递归删除子节点
//		boolean deleteRecursive = client.deleteRecursive("/zknodetest3");
//		System.out.println(deleteRecursive);
		
		//监听(订阅数据改变)相比于原始客户端连接 监听可以复用
		client.subscribeDataChanges("/test00", new IZkDataListener() {

			@Override
			public void handleDataChange(String dataPath, Object data) throws Exception {
				System.out.println("节点名称:"+dataPath+"->节点修改后的值"+data);	
			}

			@Override
			public void handleDataDeleted(String dataPath) throws Exception {
			}
		});
		try {
			//修改 可以被上面监听到
			client.writeData("/test00","xuxu");
			//如果不休眠一秒 存在延迟 看不到效果	节点名称:/test00->节点修改后的值xuxu
			TimeUnit.SECONDS.sleep(1);
			client.writeData("/test00","xuxu1");
			//节点名称:/test00->节点修改后的值xuxu1
			TimeUnit.SECONDS.sleep(1);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
//		client.subscribeChildChanges("/test00",new IZkChildListener() {
//			@Override
//			public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception {
//				System.out.println("节点名称:"+parentPath+"->"+"当前的节点列表:"+currentChilds);
//			}
//		});
//		client.delete("/zknodetest3/test1");;
	}
}

Curator

pom文件中添加

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

连接方式

package curator;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;


public class CuratorCreateSessionDemo {
    private final static String CONNECTSTRING="192.168.25.200:2181";
    public static void main(String[] args) {
        //创建会话的两种方式 normal
//        CuratorFramework curatorFramework= CuratorFrameworkFactory.
//                newClient(CONNECTSTRING,5000,5000,
//                        new ExponentialBackoffRetry(1000,3));
//        curatorFramework.start(); //start方法启动连接

//        //fluent链式风格	ExponentialBackoffRetry(1000,3)失败重连3次
        CuratorFramework curatorFramework1=CuratorFrameworkFactory.builder().connectString(CONNECTSTRING).sessionTimeoutMs(5000).
                retryPolicy(new ExponentialBackoffRetry(1000,3)).
                build();

        curatorFramework1.start();
        System.out.println("success");
    }
}

获取会话工具类

package curator;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;


public class CuratorClientUtils {

    private static CuratorFramework curatorFramework;
    private final static String CONNECTSTRING="192.168.25.200:2181";


    public static CuratorFramework getInstance(){
        curatorFramework= CuratorFrameworkFactory.
                newClient(CONNECTSTRING,5000,5000,
                        new ExponentialBackoffRetry(1000,3));
        curatorFramework.start();
        return curatorFramework;
    }
}

操作类

package curator;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.api.BackgroundCallback;
import org.apache.curator.framework.api.CuratorEvent;
import org.apache.curator.framework.api.transaction.CuratorTransactionResult;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;

import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class CuratorOperatorDemo {

    public static void main(String[] args) throws InterruptedException {
        CuratorFramework curatorFramework=CuratorClientUtils.getInstance();
        System.out.println("连接成功.........");

        //fluent风格 创建节点
//        try {
//            String result=curatorFramework.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).
//                    forPath("/curator/curator1/curator11","123".getBytes());
//
//            System.out.println(result);
//            //结果输出:
//            //  /curator/curator1/curator11
//            //  /demo1->CREATE
//            //  /demo1->SET_DATA
//        } catch (Exception e) {
//            e.printStackTrace();
//        }

        /**
         * 删除节点
         */
//        try {
//            //默认情况下,version为-1
//            curatorFramework.delete().deletingChildrenIfNeeded().forPath("/curator");
//
//        } catch (Exception e) {
//            e.printStackTrace();
//        }

        /**
         * 查询
         */
//        Stat stat=new Stat();
//        try {
//            byte[] bytes=curatorFramework.getData().storingStatIn(stat).forPath("/node11");
//            System.out.println(new String(bytes)+"-->stat:"+stat);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }

        /**
         * 更新
         */

//        try {
//            Stat stat=curatorFramework.setData().forPath("/node11","123".getBytes());
//            System.out.println(stat);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }


        /**
         * 异步操作
         */
//        ExecutorService service= Executors.newFixedThreadPool(1);
//        CountDownLatch countDownLatch=new CountDownLatch(1);
//        try {
//            curatorFramework.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).
//                    inBackground(new BackgroundCallback() {
//                        @Override
//                        public void processResult(CuratorFramework curatorFramework, CuratorEvent curatorEvent) throws Exception {
//                            System.out.println(Thread.currentThread().getName()+"->resultCode:"+curatorEvent.getResultCode()+"->"
//                            +curatorEvent.getType());
//                            countDownLatch.countDown();
//                        }
//                    },service).forPath("/enjoy","deer".getBytes());
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        countDownLatch.await();
//        service.shutdown();

        /**
         * 事务操作(curator独有的)
         */

//        try {
//            Collection<CuratorTransactionResult> resultCollections=curatorFramework.inTransaction().create().forPath("/demo1","111".getBytes()).and().
//                    setData().forPath("/demo1","111".getBytes()).and().commit();
//            for (CuratorTransactionResult result:resultCollections){
//                System.out.println(result.getForPath()+"->"+result.getType());
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
    }
}

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值