zookeeper API

4.1 IDEA环境搭建

  1. 新建project

  2. 将log4j.properties文件拷贝到项目的src目录

  3. 项目的根目录新建lib文件夹,将jar包拷贝到该目录下。

  4. File-> ->Libaries

  5. 新建包

4.2 创建ZooKeeper客户端
在该包下新建类ZooKeeperTest

package com.bjsxt.api;

import java.io.IOException;
import java.util.List;

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;
import org.apache.ZooKeeper.data.Stat;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ZooKeeperTest {

private static final int SESSION_TIMEOUT = 30000;

public static final Logger LOGGER = LoggerFactory.getLogger(ZooKeeperTest.class);

private Watcher watcher =  new Watcher() {

	public void process(WatchedEvent event) {
		LOGGER.info("process : " + event.getType());
	}
};

private ZooKeeper ZooKeeper;

/**创建ZooKeeper连接,单元测试前先执行该方法
 * @throws IOException
 */
@Before
public void connect() throws IOException {

// indicate : all servers
ZooKeeper = new ZooKeeper(“192.168.20.52:2181,192.168.20.53:2181,192.168.20.54:2181”, SESSION_TIMEOUT, watcher);
}

/**测试完毕后关闭zk连接
 */
@After
public void close() {
	try {
		ZooKeeper.close();
	} catch (InterruptedException e) {
		e.printStackTrace();
	}
}

/**
 * 创建 znode 
 *  1.CreateMode  
 *  PERSISTENT :持久化
 *  PERSISTENT_SEQUENTIAL
 *  EPHEMERAL :临时
 *  EPHEMERAL_SEQUENTIAL
 *  Access Control List: 访问控制列表
 *  https://baike.baidu.com/item/ACL/362453?fr=aladdin
 *  OPEN_ACL_UNSAFE: ANYONE CAN VISIT 
 * 
------------------------------
*/ @Test public void testCreate() { String result = null; try { result = ZooKeeper.create("/zk001", "zk001data-p".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

// result = ZooKeeper.create("/zk002", “zk002data-e”.getBytes(),
// Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
// Thread.sleep(30000);
} catch (Exception e) {
LOGGER.error(e.getMessage());
//抛出AssertionError
Assert.fail();
}
LOGGER.info(“create result : {}”, result);
}

/**
 * 删除
 */
@Test
public void testDelete() {
	 try {
		ZooKeeper.delete("/zk002", -1);
	} catch (Exception e) {
		 LOGGER.error(e.getMessage());
         //抛出AssertionError
		 Assert.fail();
	}
}

/**
 * 获取数据
 */
@Test
public void testGetData() {
	String result = null;
	 try {
		 byte[] bytes = ZooKeeper.getData("/zk001", null, null);
		 result = new String(bytes);
	} catch (Exception e) {
		 LOGGER.error(e.getMessage());
		 Assert.fail();
	}
	 LOGGER.info("getdata result------------------------------------------------- : {}", result);
}

/**查看从哪个zk服务器获取的数据,然后xshell关闭对应的zk服务器(zkServer.sh stop)
 * 然后分析日志:
 * @throws Exception
 */
@Test
public void testGetData01() throws Exception {
	String result = null;
	try {
		byte[] bytes = ZooKeeper.getData("/zk001", null, null);
		result = new String(bytes);
	} catch (Exception e) {
		LOGGER.error(e.getMessage());
		Assert.fail();
	}
	LOGGER.info("getdata result-----------------1------------------ : {}", result);
	
	Thread.sleep(30000);
	
	byte[] bytes;
	try {
		bytes = ZooKeeper.getData("/zk001", null, null);
		result = new String(bytes);
	} catch (KeeperException | InterruptedException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	LOGGER.info("getdata result-----------------2-------------------- : {}", result);
}

/**
 *   注册
 */
@Test
public void testGetDataWatch() {
	String result = null;
	 try {
		 System.out.println("get:");
		 byte[] bytes = ZooKeeper.getData("/zk001", new Watcher() {
			public void process(WatchedEvent event) {
				LOGGER.info("testGetDataWatch  watch : {}", event.getType());
				System.out.println("watcher ok");
				//testGetDataWatch();
			}
		 }, null);
		 result = new String(bytes);
	} catch (Exception e) {
		 LOGGER.error(e.getMessage());
		 Assert.fail();
	}
	 LOGGER.info("getdata result------------------------------------------ : {}", result);
	 
	 // wacth  NodeDataChanged
	 try {
		 System.out.println("set:");
		 ZooKeeper.setData("/zk001", "testSetDataWAWWW".getBytes(), -1);
		 System.out.println("set2:");
		 ZooKeeper.setData("/zk001", "testSetDataWAWWW".getBytes(), -1);
	} catch (Exception e) {
		 LOGGER.error(e.getMessage());
		 Assert.fail();
	}
	 System.out.println("over");
	try {
		Thread.sleep(30000);
	} catch (InterruptedException e) {
		e.printStackTrace();
	}
}

@Test
public void testExists() {
	Stat stat = null;
	 try {
		 stat = ZooKeeper.exists("/zk001", false);
	} catch (Exception e) {
		 LOGGER.error(e.getMessage());
		 Assert.fail();
	}
	 Assert.assertNotNull(stat);
	 LOGGER.info("exists result : {}", stat.getCzxid());
}

@Test
public void testSetData() {
	Stat stat = null;
	 try {
		 stat = ZooKeeper.setData("/zk001", "testSetData".getBytes(), -1);
	} catch (Exception e) {
		 LOGGER.error(e.getMessage());
		 Assert.fail();
	}
	 Assert.assertNotNull(stat);
	 LOGGER.info("exists result : {}", stat.getVersion());	
}

@Test
public void testExistsWatch1() {
	Stat stat = null;
	 try {
		 stat = ZooKeeper.exists("/zk001", true);
	} catch (Exception e) {
		 LOGGER.error(e.getMessage());
		 Assert.fail();
	}
	 Assert.assertNotNull(stat);
	 
	 try {
		ZooKeeper.delete("/zk001", -1);
	} catch (Exception e) {
		e.printStackTrace();
	}
}

@Test
public void testExistsWatch2() {
	Stat stat = null;
	 try {
		 stat = ZooKeeper.exists("/zk002", new Watcher() {
			@Override
			public void process(WatchedEvent event) {
				LOGGER.info("testExistsWatch2  watch : {}", event.getType());
			}
		 });
	} catch (Exception e) {
		 LOGGER.error(e.getMessage());
		 Assert.fail();
	}
	 Assert.assertNotNull(stat);

	 try {
		ZooKeeper.setData("/zk002", "testExistsWatch2".getBytes(), -1);
	} catch (Exception e) {
		e.printStackTrace();
	}
	 
	 try {
		ZooKeeper.delete("/zk002", -1);
	} catch (Exception e) {
		e.printStackTrace();
	}
}

/**
 */
@Test
public void testGetChild() {
	 try {
		 ZooKeeper.create("/zk/001", "001".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
		 ZooKeeper.create("/zk/002", "002".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
		 
		 List list = ZooKeeper.getChildren("/zk", true);
		for (String node : list) {
			LOGGER.info("fffffff {}", node);
		}
	} catch (Exception e) {
		 LOGGER.error(e.getMessage());
		 Assert.fail();
	}
}

}

框架实现的客户端和服务器之间的故障转移过程
注册Watcher,查询注册watch,增删改触发watcher
如果是多次增删改,回调方法调用几次?
1、watcher事件是一次性的
2、是增删改触发watcher,但是watcher是线程异步执行
3、watcher可以反复注册
如何平滑反复注册?在回调方法中迭代调用即可。

5 分布式协调案例
如何实现“跨虚拟机”的调用,它就是 RMI(Remote Method Invocation,远程方法调用)。例如,服务A 在 JVM1 中运行,服务B 在 JVM2 中运行,服务A 与 服务B 可相互进行远程调用,就像调用本地方法一样,这就是 RMI。在分布式系统中,我们使用 RMI 技术可轻松将 服务提供者(Service Provider)与 服务消费者(Service Consumer)进行分离,充分体现组件之间的弱耦合,系统架构更易于扩展。

我们先从通过一个最简单的 RMI 服务与调用示例,快速掌握 RMI 的使用方法,然后指出 RMI 的局限性,最后笔者对此问题提供了一种简单的解决方案,即使用 ZooKeeper 轻松解决 RMI 调用过程中所涉及的问题。

你可能感兴趣的:(HCIA-BD)