zk复习笔记1

  • 节点类型

  1. 持久节点(PERSISTENT) 
  2. 持久顺序节点(PERSISTENT_SEQUENTIAL)
  3. 临时节点(EPHEMERAL) 
  4. 临时顺序节点(EPHEMERAL_SEQUENTIAL)

create -e 临时 -s 顺序

  • acl

CREATE:表示创建子节点的权限
READ:表示获取节点数据和子节点列表的权限
WRITE:表示更新节点数据的权限
DELETE:表示删除子节点的权限
ADMIN:表示设置节点ACL的权限

1> digest

语法:digest:username:BASE64(SHA1(password)):cdrwa 
digest:是授权方式 
username:BASE64(SHA1(password)):是id部分 
cdrwa:权限部份 

用户名+密码授权访问方式,也是常用的一种授权策略。id部份是用户名和密码做sha1加密再做BASE64加密后的组合,比如设置一个节点的用户名为yangxin,密码为123456,则表示方式为:yangxin:BASE64(SHA1(123456)) ⇒ yangxin:ACFm5rWnnKn9K9RN/Oc8qEYGYDs=。密码加密需要用到zk的一个工具类来生成,如下所示:

shell> java -jar zookeeper/zookeeper-3.4.9.jar org.apache.zookeeper.server.auth.DigestAuthenticationProvider yangxin:123456
yangxin:123456->yangxin:ACFm5rWnnKn9K9RN/Oc8qEYGYDs=

下面是演示创建节点,并添加授权信息操作节点的示例:

## 创建节点/node_05
shell> create /node_05 data
Created /node_05
## 设置权限
shell> setAcl /node_05 digest:yangxin:ACFm5rWnnKn9K9RN/Oc8qEYGYDs=:cdrwa
cZxid = 0x8e
ctime = Mon Nov 14 21:38:52 CST 2016
mZxid = 0x8e
mtime = Mon Nov 14 21:38:52 CST 2016
pZxid = 0x8e
cversion = 0
dataVersion = 0
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
## 获取节点刚刚设置的权限
shell> getAcl /node_05
'digest,'yangxin:ACFm5rWnnKn9K9RN/Oc8qEYGYDs=
: cdrwa

## 没有授权,创建节点失败
shell> create /node_05/node_05_01 data
Authentication is not valid : /node_05/node_05_01

## 添加授权信息
shell> addauth digest yangxin:123456

## 添加授权信息后,就可以正常操作了
shell> create /node_05/node_05_01 data
Created /node_05/node_05_01

2> ip

基于客户端IP地址校验,限制只允许指定的客户端能操作znode。 
比如,设置某个节点只允许IP为192.168.1.100的客户端能读写该写节点的数据:ip:192.168.1.100:rw

shell> setAcl /node_08 ip:192.168.1.100:rw

3> world

语法:world:anyone:cdrwa 
创建节点默认的scheme,所有人都可以访问。如下所示:

shell> create /node_06 data
Created /node_06
shell> getAcl /node_06
'world,'anyone
: cdrwa

4> super

添加方式:

只能在启动服务器的时候添加。

假设这个超管是:super:admin,通过代码得到其哈希值:

String m = DigestAuthenticationProvider.generateDigest("super:admin");  
super:xQJmxLMiHGwaqBvst5y6rkB6HQs=
这就是脚本中启动zk的命令,默认只有以上两个配置项,我们需要加一个超管的配置项:
-Dzookeeper.DigestAuthenticationProvider.superDigest=admin:015uTByzA4zSglcmseJsxTo7n3c=
之后启动zk集群,输入如下命令添加权限:
addauth digest super:admin 
package com.aicong.test.helloZookeeper;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooDefs.Perms;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Id;
import org.apache.zookeeper.server.auth.DigestAuthenticationProvider;


public class CreateNodeSyncAuth implements Watcher { 

	private static ZooKeeper zookeeper;
	private static boolean somethingDone = false;
	
	public static void main(String[] args) throws IOException, InterruptedException {
		zookeeper = new ZooKeeper("112.74.219.174:2181",5000,new CreateNodeSyncAuth());
		System.out.println(zookeeper.getState());
		
		Thread.sleep(Integer.MAX_VALUE);
	}
	
	/*
	 * 权限模式(scheme): ip, digest
	 * 授权对象(ID)
	 * 		ip权限模式:  具体的ip地址
	 * 		digest权限模式: username:Base64(SHA-1(username:password))
	 * 权限(permission): create(C), DELETE(D),READ(R), WRITE(W), ADMIN(A) 
	 * 		注:单个权限,完全权限,复合权限
	 * 
	 * 权限组合: scheme + ID + permission
	 * 
	 * 
	 * 
	 * */
	
	private void doSomething(){
		try {
			//创建节点的时候要求权限验证
			//基于IP
			ACL aclIp = new ACL(Perms.READ,new Id("ip","112.74.219.174"));
			//基于用户名密码
			ACL aclDigest = new ACL(Perms.READ|Perms.WRITE,new Id("digest",DigestAuthenticationProvider.generateDigest("jike:123456")));
			ArrayList<ACL> acls = new ArrayList<ACL>();
			acls.add(aclDigest);
			acls.add(aclIp);
			//zookeeper.addAuthInfo("digest", "jike:123456".getBytes());			
			String path = zookeeper.create("/node_10", "123".getBytes(), acls, CreateMode.PERSISTENT);
			System.out.println("return path:"+path);
			
			somethingDone = true;
			
		} catch (KeeperException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	@Override
	public void process(WatchedEvent event) {
		// TODO Auto-generated method stub
		System.out.println("收到事件:"+event);
		if (event.getState()==KeeperState.SyncConnected){
			if (!somethingDone && event.getType()==EventType.None && null==event.getPath()){
				doSomething();
			}
		}
	}
	
}
调用方可以使用代码:
package com.aicong.test.helloZookeeper;

import java.io.IOException;

import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;


public class GetDataSyncAuth implements Watcher{
	
	
    private static ZooKeeper zooKeeper;
    private static Stat stat = new Stat();
    
	public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
		
		zooKeeper = new ZooKeeper("112.74.219.174:2181",5000,new GetDataSyncAuth());
		System.out.println(zooKeeper.getState().toString());
	
		Thread.sleep(Integer.MAX_VALUE);
		

	}
	
	private void doSomething(ZooKeeper zookeeper){
		//权限验证	
		zooKeeper.addAuthInfo("digest", "jike:1234".getBytes());
		
			try {
				System.out.println(new String(zooKeeper.getData("/node_4", true, stat)));
			} catch (KeeperException e) {
				e.printStackTrace();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		
	}

	@Override
	public void process(WatchedEvent event) {
		// TODO Auto-generated method stub

		if (event.getState()==KeeperState.SyncConnected){
			if (event.getType()==EventType.None && null==event.getPath()){
				doSomething(zooKeeper);
			}else{				
				if (event.getType()==EventType.NodeDataChanged){
					try {
						System.out.println(new String(zooKeeper.getData(event.getPath(), true, stat)));
						System.out.println("stat:"+stat);
					} catch (KeeperException e) {
						e.printStackTrace();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					
				}	
			}
		
		}
	}

}


  • curator
package com.zk.dev.curator;

import java.util.List;

import org.apache.curator.RetryPolicy;
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.CuratorWatcher;
import org.apache.curator.framework.recipes.cache.NodeCache;
import org.apache.curator.framework.recipes.cache.NodeCacheListener;
import org.apache.curator.framework.recipes.cache.PathChildrenCache;
import org.apache.curator.framework.recipes.cache.PathChildrenCache.StartMode;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.data.Stat;

public class CuratorClientTest {
	private CuratorFramework client = null;

	public CuratorClientTest() {
		RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
		client = CuratorFrameworkFactory.builder()
				.connectString("localhost:2181,localhost:2182")
				.sessionTimeoutMs(10000).retryPolicy(retryPolicy)
				.namespace("base").build();
		client.start();
	}

	public void closeClient() {
		if (client != null)
			this.client.close();
	}

	public void createNode(String path, byte[] data) throws Exception {
		client.create().creatingParentsIfNeeded()
				.withMode(CreateMode.PERSISTENT).withACL(Ids.OPEN_ACL_UNSAFE)
				.forPath(path, data);
	}

	public void deleteNode(String path, int version) throws Exception {
		// client.delete().guaranteed().deletingChildrenIfNeeded().withVersion(version).inBackground(new
		// DeleteCallBack()).forPath(path);
		client.delete().guaranteed().deletingChildrenIfNeeded().withVersion(version)
				.inBackground(new DeleteCallBack()).forPath(path);

	}

	public void readNode(String path) throws Exception {
		Stat stat = new Stat();
		byte[] data = client.getData().storingStatIn(stat).forPath(path);
		System.out.println("读取节点" + path + "的数据:" + new String(data));
		System.out.println(stat.toString());
	}

	public void updateNode(String path, byte[] data, int version)
			throws Exception {
		client.setData().withVersion(version).forPath(path, data);
	}

	public void getChildren(String path) throws Exception {
		List<String> children = client.getChildren().usingWatcher(new WatcherTest()).forPath("/curator");
		for (String pth : children) {
			System.out.println("child=" + pth);
		}
	}

	public void addNodeDataWatcher(String path) throws Exception {
		final NodeCache nodeC = new NodeCache(client, path);
		nodeC.start(true);
		nodeC.getListenable().addListener(new NodeCacheListener() {
			public void nodeChanged() throws Exception {
				String data = new String(nodeC.getCurrentData().getData());
				System.out.println("path=" + nodeC.getCurrentData().getPath()
						+ ":data=" + data);
			}
		});
	}

	public void addChildWatcher(String path) throws Exception {
		final PathChildrenCache cache = new PathChildrenCache(this.client,
				path, true);
		cache.start(StartMode.POST_INITIALIZED_EVENT);//ppt中需要讲StartMode
		System.out.println(cache.getCurrentData().size());
		//byte childone[] = cache.getCurrentData().get(0).getData();
//		System.out.println("childone:"
//				+ cache.getCurrentData().get(0).getPath() + ";data="
//				+ new String(childone));
		cache.getListenable().addListener(new PathChildrenCacheListener() {
			public void childEvent(CuratorFramework client,
					PathChildrenCacheEvent event) throws Exception {
				if(event.getType().equals(PathChildrenCacheEvent.Type.INITIALIZED)){
					System.out.println("客户端子节点cache初始化数据完成");
					System.out.println("size="+cache.getCurrentData().size());
				}else if(event.getType().equals(PathChildrenCacheEvent.Type.CHILD_ADDED)){
					System.out.println("添加子节点:"+event.getData().getPath());
					System.out.println("修改子节点数据:"+new String(event.getData().getData()));
				}else if(event.getType().equals(PathChildrenCacheEvent.Type.CHILD_REMOVED)){
					System.out.println("删除子节点:"+event.getData().getPath());
				}else if(event.getType().equals(PathChildrenCacheEvent.Type.CHILD_UPDATED)){
					System.out.println("修改子节点数据:"+event.getData().getPath());
					System.out.println("修改子节点数据:"+new String(event.getData().getData()));
				}
			}
		});
	}
	public class DeleteCallBack implements BackgroundCallback {

		public void processResult(CuratorFramework client, CuratorEvent event)
				throws Exception {
			// TODO Auto-generated method stub
			System.out.println(event.getPath()+",data="+event.getData());
			System.out.println("event type="+event.getType());
			System.out.println("event code="+event.getResultCode());

		}

	}
	public class WatcherTest implements CuratorWatcher {

		public void process(WatchedEvent event) throws Exception {
			// TODO Auto-generated method stub
			System.out.println(event.getPath());
		}

	}

	public static void main(String[] args) {
		CuratorClientTest ct = null;
		try {
			ct = new CuratorClientTest();
			// ct.createNode("/curator/test10/node1", "test-node1".getBytes());
			//ct.readNode("/curator/test/node1");
			//ct.getChildren("/curator");
			// ct.updateNode("/curator/test/node1", "test-node1-new".getBytes(),
			// 0);
			// ct.readNode("/curator/test/node1");
			// ct.deleteNode("/curator/test10", 0);

			ct.addNodeDataWatcher("/curator/test7");
			ct.addChildWatcher("/curator");
			Thread.sleep(300000);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			ct.closeClient();
		}

	}

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值