Zookeeper安装(四)——Zookeeper Java API

Zookeeper Java API

概述


  1. Zookeeper提供了Java API方便我们来操作zk服务,可以通过maven引入zk的相关依赖包。
  2. 通过org.apache.zookeeper.Zookeeper类创建连接zk服务器的示例对象,在创建过程中给定zk服务器地址、会话持续时间以及监视器三个参数,当连接创建成功后,通过Zookeeper实例提供的接口(或方法)来和服务器进行交互。
  3. Pom.xml文件依赖内容如下:
<dependencies>
		<dependency>
			<groupId>org.apache.zookeeper</groupId>
			<artifactId>zookeeper</artifactId>
			<version>3.4.5</version>
		</dependency>
</dependencies>

 

 

连接创建

使用Zookeeper类来表示连接,创建的该实例对象有四个构造方法来调用:

Zookeeper(connectString,sessionTimeout,watcher); ★//最常用
Zookeeper(connectString,sessionTimeout,watcher,canBeReadOnly);★//最常用
Zookeeper(connectString,sessionTimeout, watcher,sessionId,sessionPasswd) ;
Zookeeper(connectString,sessionTimeout,watcher,sessionId,sessionPasswd,canBeReadOnly);

其中第一个构造方法底层调用第二个构造方法,只是canBeReadOnly参数设置为false。

 

参数说明: 

1、connectString:参数为zk集群服务器的连接url,当给定路径的时候,表示所有的操作都是基于该路径进行操作的(路径只可以添加到最后)。

例如:”master.com:2181, master.com:2182, master.com:2183/app”。

2、sessionTimeout:为会话过期时间,以毫秒为单位,一般设置为tickTime的3-4倍;

客户端和服务器端之间的连接通过心跳包进行维系,如果心跳包超过这个指定时间则认为会话超时失效。一般设置为private static final int SESSION_TIMEOUT = 30000; 

3、watcher:是监视器,用于触发相应事件,可以为空(表示不需要观察者);

4、canBeReadOnly:是否支持只读连接,默认为false。

5、sessionIdSessionPassword :会话编号 会话密码,用来实现会话恢复。

**注意1:整个创建会话的过程是异步的,构造方法会在初始化连接后即返回,并不代表真正建立好了一个会话,此时会话处于”CONNECTING”状态。 
**注意2:当会话真正创建起来后,服务器会发送事件通知给客户端,只有客户端获取到这个通知后,会话才真正建立。

 

 

新增/创建节点

  1. ZK中新增子节点和创建节点其实是同一个含义,创建一个节点其实就相当于在根目录下新增一个子节点,
  2. 注意:zk不支持为不存在的父节点创建子节点(不支持循环创建)。
  3. 创建节点的时候要求指明节点被创建的类型(CreateMode)。
  4. 调用Zookeeper实例的create方法,需要给定的参数有:

 

//同步方式创建

String create(final String path,byte data[],List acl,CreateMode createMode);

说明:返回的是该节点的路径名称,例如:/test/zh_1324578

 

//异步方式创建【不常用】

void create(final String path,byte data[],List acl,CreateMode createMode,StringCallback cb,Object ctx);

说明:此创建方式是通过回调函数来相应操作。

 

参数说明:

1. path——要创建的数据节点的路径

2. data []——节点创建时初始数据内容

3. acl——节点acl安全策略,不考虑权限的情况下给定:ids.OPEN_ACL_UNSAFE。

4. createMode——创建模式

CreateMode类型名称详解
PERSISTENT持久会话结束后不会被自动删除
PERSISTENT_SEQUENTIAL持久顺序在节点名称后添加一个序列号(单调递增),不会自动删除
EPHEMERAL临时在会话结束后自动被删除
EPHEMERAL_SEQUENTIAL临时顺序在会话被结束后自动删除,会在给定的path节点名称后添加一个序列号(单调递增)

5. cb——回调接口

6. ctx——传递对象,用来在回调方法中使用 通常是个上下文对象

**注意:不支持递归创建,即不能在无父节点的情况下创建出子节点,尝试创建已经存在的节点将失败并抛出异常,在不需要进行任何权限控制时,只需传入Ids.OPEN_ACL_UNSAFE即可。

 

 

删除节点

当系统不需要某个配置节点的时候,或者某个节点失效的时候,使用delete方法可以删除该节点;

**注意:无法删除存在子节点的节点,即如果要删除一个节点,必须要先删除其所有子节点【不支持递归删除】

删除要求:被删除的节点木有子节点,并且需要给定明确的版本号(可以给定-1,表示不管版本号是什么都删除) 

例如:

client.delete("/root/child", -1);//不管版本号直接删除

client.delete("/root", 0);//直接删除版本号为0的root节点,如果zk上root节点的版本是0,那么删除成功,否则抛出异常。

 

  • public void delete(final String path,int version)

说明:无返回类型

  • public void delete(final String path,int version,VoidCallback cb,Object ctx)

说明:无返回类型

 

 

获取子节点名称列表信息

//同步方式

List getChildren(final String path,Watcher watcher)

List getChildren(String path,boolean watch)

List getChildren(final String path,Watcher watcher,Stat stat)

List getChildren(String path,boolean watch,Stat stat)

    说明:上述返回的都是path路径下的节点名称

//异步方式

void getChildred(final String path,Watcher watcher,ChildrenCallback cb,Object ctx)

void getChildred(String path,boolean watch,ChildrednCallback cb,Object ctx)

void getChildred(final String path,Watcher watcher,Children2Callback cb,Object ctx)

void getChildred(String path,boolean watch,Children2Callback cb,Object ctx)

 

参数说明

  1. path 要创建的数据节点的路径
  2. watcher 观察者,一旦在本子节点获取之后,子节点列表发生变更,服务器端向客户端发送消息,触发watcher中的回调。注意,仅仅是通知而已,如果需要新的子节点列表,需要自己再次去获取。允许传入null。
  3. watch 表明是否需要注册一个Watcher。为true则通知默认到默认watcher,如果为false则不使用
  4. cb 回掉函数
  5. ctx 上下文对象
  6. stat 指定数据节点的状态信息。用法是在接口中传入一个旧的stat变量,该stat变量会在方法执行过程中,被来自服务端响应的新stat对象替换。

 

 

获取节点数据

**注意:可以通过注册Watcher进行监听,一旦该节点数据被更新会通知客户端

例如:String data=new String(client.getData("/root/child", false, null));//获取数据,不进行wath机制监控,state状态信息为空

//同步方式

byte [] getData(final String path,Watcher watcher, Stat stat)

byte [] getData(String path,boolean watch, Stat stat)

 //异步方式

void getData(final String path,Watcher watcher, DataCallback cb,Object ctx) 

void getData(String path,boolean watch, DataCallback cb,Object ctx)

 

 

更新数据

当节点内容需要进行改变的时候可以调用setDate方法设置节点内容;

注意:设置节点内容时需要给定版本号,zk服务器会检查该版本号;

如果当前节点和你给定的版本号不一致,那么直接抛出异常,否则更新成功。

如果给定的版本号为-1,那么表示不检查。

 例如:client.setData("/root/child", "new-data".getBytes(), -1);//设置新的内容

//同步方式

Stat setData(final String path,byte data[],int version)  //version

   说明:可以传入-1,表明要基于最新版本进行更新操作

//异步方式

void setData(final String path,byte data[],int version,StatCallback cb,Object ctx)

 

 

检查节点是否存在

**注意:可以通过注册Watcher进行监听,一旦节点被创建、删除、数据被更新都会通知客户端

//同步方式

public Stat exists(final String path,Watcher watcher)

public Stat exists(String path,boolean watch)

 //异步方式

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

public Stat exists(String path,boolean watch,StatCallback cb,Object ctx)

 

 

其他方法 

  1. addAuthInfo:添加权限验证scheme 信息
  2. getACL:获取节点的权限列表
  3. setACL:设置节点的权限列表
  4. getState:获取当前连接的States 信息

 

 

代码案例

创建节点

package com.master.zookeeper;

import java.io.IOException;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;

public class DemoCreate {
	public static String Url_1 = "192.168.1.111,192.168.1.111:2182,192.168.1.111:2183";// 端口号不一定,随意选择
	public static String Url_2 = "192.168.1.111,192.168.1.111:2182,192.168.1.111:2183/app";// 端口号不一定,随意选择,给定路径

	public static void main(String[] args) {
//		test1();
//		test2();

	}
	
	

	/**
	 * 测试创建连接的时候给定路径
	 * @throws IOException
	 * @throws KeeperException
	 * @throws InterruptedException
	 */
	static void test2() throws IOException, KeeperException, InterruptedException {
		ZooKeeper client = new ZooKeeper(Url_2, 2000, new Watcher() {

			@Override
			public void process(WatchedEvent arg0) {

			}
		});

		// 创建永久节点
		String result = client.create("/root", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
		System.out.println("创建永久节点/root结果:" + result);

		// 添加子节点——永久顺序节点
		result = client.create("/root/child", "child".getBytes(), Ids.OPEN_ACL_UNSAFE,
				CreateMode.PERSISTENT_SEQUENTIAL);
		System.out.println("添加节点/root/child结果:" + result);

		// 创建临时节点
		result = client.create("/tmp", "".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
		System.out.println("创建临时节点/root结果:" + result);

		// 创建临时顺序节点
		result = client.create("/tmp", "".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
		System.out.println("创建临时顺序节点/root结果:" + result);

		Thread.sleep(10000);
		// 关闭会话
		client.close();
	}
	
	static void test1() throws IOException, KeeperException, InterruptedException {
		ZooKeeper client = new ZooKeeper(Url_1, 2000, new Watcher() {
			
			@Override
			public void process(WatchedEvent arg0) {
				
			}
		});
		
		// 创建永久节点
		String result = client.create("/root", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
		System.out.println("创建永久节点/root结果:" + result);
		
		// 添加子节点——永久顺序节点
		result = client.create("/root/child", "child".getBytes(), Ids.OPEN_ACL_UNSAFE,
				CreateMode.PERSISTENT_SEQUENTIAL);
		System.out.println("添加节点/root/child结果:" + result);
		
		// 创建临时节点
		result = client.create("/tmp", "".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
		System.out.println("创建临时节点/root结果:" + result);
		
		// 创建临时顺序节点
		result = client.create("/tmp", "".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
		System.out.println("创建临时顺序节点/root结果:" + result);
		
		Thread.sleep(5000);
		// 关闭会话
		client.close();
	}

}

删除节点

package com.master.zookeeper;

import java.io.IOException;

import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;

public class DemoDelete {
	public static String Url_1 = "192.168.1.111,192.168.1.111:2182,192.168.1.111:2183";// 端口号不一定,随意选择
	public static String Url_2 = "192.168.1.111,192.168.1.111:2182,192.168.1.111:2183/app";// 端口号不一定,随意选择,给定路径
	
	public static void main(String[] args) {
		
	}

	static void test1() throws IOException, InterruptedException, KeeperException{
		ZooKeeper client = new ZooKeeper(Url_1, 2000, new Watcher() {
			@Override
			public void process(WatchedEvent arg0) {
			}
		});
		
		//删除节点 /root/child
		client.delete("/root/child", -1);
		//给定具体的版本号进行删除root
		client.delete("/root", client.exists("/root", false).getVersion());
		
		//删除文件夹——递归删除
		client.delete("/app", -1);//不支持递归删除
		
		client.close();
	}

}

设置获取节点数据

package com.master.zookeeper;

import java.io.IOException;

import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;

/**
 * 演示设置数据和读取数据
 * 
 * @author Administrator
 *
 */
public class DemoData {
	public static String Url_1 = "192.168.1.111,192.168.1.111:2182,192.168.1.111:2183";// 端口号不一定,随意选择
	public static String Url_2 = "192.168.1.111,192.168.1.111:2182,192.168.1.111:2183/app";// 端口号不一定,随意选择,给定路径

	public static void main(String[] args) {

	}

	static void test1() throws IOException, InterruptedException, KeeperException {
		ZooKeeper client = new ZooKeeper(Url_1, 2000, new Watcher() {
			@Override
			public void process(WatchedEvent arg0) {
			}
		});

		String data = "";
		// 获取数据
		// 第一种方式:当第二个参数为true的时候,会使用创建client时候给定的watcher实例进行监控
		data = new String(client.getData("/root/child", false, null));
		// 第二种方式:采用给定的监视器进行监控
//		data = new String(client.getData("/root/child", new Watcher() {
//			@Override
//			public void process(WatchedEvent arg0) {
//			}
//		}, null));

		// 设置数据
		client.setData("/root/child", "new-data".getBytes(), -1);
		
		// 再重新获取数据
		data = new String(client.getData("/root/child", new Watcher() {
			@Override
			public void process(WatchedEvent arg0) {
			}
		}, null));
		
		client.close();
	}

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值