zookeeper 应用开发
由于zookeeper的client只有zookeeper一个对象,使用也比较简单,所以就不许要文字说明了,在代码中注释下就ok 了。
1、测试用的main方法
package ClientExample;
public class TestMain {
public static void main(String[] args) {
/*
* 测试流程
* 1、创建sever1的连接client1,并且创建一个永久性的/test节点
* 2、创建一个针对server1的临时节点
* 3、创建server2的连接client21,并创建一个针对server2的临时节点
* 4、创建server3的连接client3,并创建一个针对server3的临时节点
* 5、分别查看client1、client2、client3的三个节点的字节点数量,确定是否同步成功
* 6、修改client1的临时节点内容,然后在在client2和client3中查看
* 7、kill掉client3的线程,然后检查是watcher是否有通知给client1和client2
*/
Thread t1= new ClientThread("127.0.0.1:2181","server1",false);
Thread t2= new ClientThread("127.0.0.1:2182","server2",false);
Thread t3= new ClientThread("127.0.0.1:2183","server3",false);
Thread t4= new ClientThread("127.0.0.1:2181","server4",false);
t1.start();
t2.start();
t3.start();
t4.start();
ControlThread c = new ControlThread(t1, t2, t3, t4);
c.start();
int i=0;
while(true)
{
i++;
i--;
}
/*
* 测试控制台输出:
* connectIP:server4,path:null,state:SyncConnected,type:None
* connectIP:server3,path:/test,state:SyncConnected,type:NodeChildrenChanged
* connectIP:server4,path:/test/server4,state:SyncConnected,type:NodeCreated
* 。。。。。。。。。。。
*
* connectIP:server2,path:null,state:Disconnected,type:None
server2exception,KeeperErrorCode = ConnectionLoss for /test
connectIP:newServer1,path:null,state:SyncConnected,type:None
connectIP:server1,path:/test,state:SyncConnected,type:NodeChildrenChanged
connectIP:server4,path:/test/server2,state:SyncConnected,type:NodeDeleted
connectIP:server4,path:/test,state:SyncConnected,type:NodeChildrenChanged
connectIP:newServer1,path:/test,state:SyncConnected,type:NodeChildrenChanged
connectIP:server3,path:/test/server2,state:SyncConnected,type:NodeDeleted
connectIP:server3,path:/test,state:SyncConnected,type:NodeChildrenChanged
*/
}
}
2、zookeeper封装的接口:
package ClientExample; import java.io.IOException;
import java.util.List;
import org.apache.zookeeper.KeeperException;
/**
* zookeeper的操作封装接口,实现了常用的操作
* 创建、销毁、写入、修改、查询等。
* @author ransom
*
*/
public interface ServerOperation {
void init(String address,String serverName) throws IOException;
void destroy() throws InterruptedException;
List<String> getChilds(String path) throws KeeperException,
InterruptedException;
String getData(String path) throws KeeperException, InterruptedException;
void changeData(String path, String data) throws KeeperException,
InterruptedException;
void delData(String path) throws KeeperException, InterruptedException;
void apendTempNode(String path, String data) throws KeeperException,
InterruptedException;
void apendPresistentNode(String path, String data) throws KeeperException,
InterruptedException; void delNode(String path) throws KeeperException, InterruptedException;
boolean exist(String path) throws KeeperException, InterruptedException;
}
3、接口的实现:
package ClientExample; import java.io.IOException;
import java.util.List;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.ZooDefs.Ids;
public class ServerConnector implements ServerOperation {
// 创建一个Zookeeper实例,第一个参数为目标服务器地址和端口,第二个参数为Session超时时间,第三个为节点变化时的回调方法
private ZooKeeper zk = null;
public void init(String address,String serverName) throws IOException {
zk = new ZooKeeper(address, 500000,
new MultiWatcher(serverName));
}
@Override
public void destroy() throws InterruptedException {
// TODO Auto-generated method stub
if (zk != null) {
zk.close();
}
}
@Override
public List<String> getChilds(String path) throws KeeperException, InterruptedException {
// TODO Auto-generated method stub
if (zk != null) {
return zk.getChildren(path, true);
}
return null;
}
@Override
public String getData(String path) throws KeeperException, InterruptedException {
// TODO Auto-generated method stub
if (zk != null) {
// 取得/root/childone节点下的数据,返回byte[]
byte[] b = zk.getData(path, true, null);
return new String(b);
}
return null;
}
@Override
public void changeData(String path,String data) throws KeeperException, InterruptedException {
// TODO Auto-generated method stub
if (zk != null) {
// 修改节点/root/childone下的数据,第三个参数为版本,如果是-1,那会无视被修改的数据版本,直接改掉
zk.setData(path, data.getBytes(),-1);
}
}
@Override
public void delData(String path) throws InterruptedException, KeeperException {
// TODO Auto-generated method stub
if (zk != null) {
// 删除/root/childone这个节点,第二个参数为版本,-1的话直接删除,无视版本
zk.delete(path, -1);
}
}
@Override
public void delNode(String path) throws InterruptedException, KeeperException {
// TODO Auto-generated method stub
if (zk != null) {
zk.delete(path, -1);
}
}
@Override
public boolean exist(String path) throws KeeperException,
InterruptedException {
// TODO Auto-generated method stub
if (zk != null) {
return zk.exists(path, true)!=null;
}
return false;
}
@Override
public void apendTempNode(String path, String data) throws KeeperException,
InterruptedException {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
if (zk != null)
{
// 创建一个节点root,数据是mydata,不进行ACL权限控制,节点为永久性的(即客户端shutdown了也不会消失)
/*
* 创建一个给定的目录节点 path, 并给它设置数据,
* CreateMode 标识有四种形式的目录节点,分别是
* PERSISTENT:持久化目录节点,这个目录节点存储的数据不会丢失;
* PERSISTENT_SEQUENTIAL:顺序自动编号的目录节点,这种目录节点会根据当前已近存在的节点数自动加 1,然后返回给客户端已经成功创建的目录节点名;
* EPHEMERAL:临时目录节点,一旦创建这个节点的客户端与服务器端口也就是 session 超时,这种节点会被自动删除;
* EPHEMERAL_SEQUENTIAL:临时自动编号节点
*/
zk.create(path, data.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
}
}
@Override
public void apendPresistentNode(String path, String data)
throws KeeperException, InterruptedException {
// TODO Auto-generated method stub
if (zk != null)
{
// 创建一个节点root,数据是mydata,不进行ACL权限控制,节点为永久性的(即客户端shutdown了也不会消失)
/*
* 创建一个给定的目录节点 path, 并给它设置数据,
* CreateMode 标识有四种形式的目录节点,分别是
* PERSISTENT:持久化目录节点,这个目录节点存储的数据不会丢失;
* PERSISTENT_SEQUENTIAL:顺序自动编号的目录节点,这种目录节点会根据当前已近存在的节点数自动加 1,然后返回给客户端已经成功创建的目录节点名;
* EPHEMERAL:临时目录节点,一旦创建这个节点的客户端与服务器端口也就是 session 超时,这种节点会被自动删除;
* EPHEMERAL_SEQUENTIAL:临时自动编号节点
*/
zk.create(path, data.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
}
}
4、一个控制的线程,主要用来强制kill掉连接的线程
package ClientExample;
public class ControlThread extends Thread{
public ControlThread(Thread t1,Thread t2,Thread t3,Thread t4)
{
list[0]=t1;
list[1]=t2;
list[2]=t4;
list[3]=t4;
}
private Thread[] list = new Thread[4];
private int num=0;
public void run()
{
while(true)
{
if(num==7)
{
list[2].stop();
System.out.println("kill server3");
}
if(num==15)
{
list[3].stop();
System.out.println("kill server4");
}
try {
sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
5、watcher 的实现:
package ClientExample; import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState;
/**
* 提供给多个client使用的watcher
* @author ransom
*
*/
public class MultiWatcher implements Watcher{
public MultiWatcher(String address)
{
connectAddress=address;
} private String connectAddress=null; @Override
public void process(WatchedEvent event) {
// TODO Auto-generated method stub
String outputStr="";
if(connectAddress!=null){
outputStr+="connectIP:"+connectAddress;
}
outputStr+=",path:"+event.getPath();
outputStr+=",state:"+event.getState();
outputStr+=",type:"+event.getType(); System.out.println(outputStr);
}
}
6、client 运行 的Thread
package ClientExample; import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import org.apache.zookeeper.KeeperException;
public class ClientThread extends Thread{
public ClientThread(String address,String serverName,boolean islog)
{
this.address=address;
this.serverName=serverName;
try {
otherOperation();
} catch (KeeperException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.islog=islog;
}
private boolean islog=true;
private final String rootPath = "/test";
private String address;
private String serverName;
private ServerOperation operationCient = null; public void run()
{
if(operationCient==null)
{
System.out.println("operationCient=null");
return;
} while(true){
try {
if(islog){
System.out.println(serverName+",loopTime:"+getNowTime());
}
observerChildData(rootPath);
} catch (KeeperException e) {
// TODO Auto-generated catch block
System.out.println(serverName+"exception,"+e.getLocalizedMessage());
try {
operationCient= new ServerConnector();
operationCient.init("127.0.0.1:2181","newServer1");
} catch (IOException e1) {
// TODO Auto-generated catch block
System.out.println(serverName+" reconnect exception,"+e.getLocalizedMessage());
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} } /*
* 测试流程
* 1、创建sever1的连接client1,并且创建一个永久性的/test节点
* 2、创建一个针对server1的临时节点
* 3、创建server2的连接client21,并创建一个针对server2的临时节点
* 4、创建server3的连接client3,并创建一个针对server3的临时节点
* 5、分别查看client1、client2、client3的三个节点的字节点数量,确定是否同步成功
* 6、修改client1的临时节点内容,然后在在client2和client3中查看
* 7、kill掉client3的线程,然后检查是watcher是否有通知给client1和client2
*/ private void otherOperation() throws KeeperException, InterruptedException
{
operationCient= new ServerConnector();
try {
operationCient.init(address,serverName);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} if(operationCient==null)
{
System.out.println("operationCient=null");
return;
}
if(!operationCient.exist(rootPath))
{
operationCient.apendPresistentNode(rootPath, "this node is creat by " + serverName);
} //添加临时节点
if(!operationCient.exist(rootPath+"/"+serverName))
{
operationCient.apendTempNode(rootPath+"/"+serverName, "this node is creat by " + serverName);
}
observerChildData("/test"); //修改临时节点内容
operationCient.changeData(rootPath+"/"+serverName, "this node is changed by " + serverName);
//临时节点内容
List<String> childs=operationCient.getChilds(rootPath);
for(String str : childs)
{
System.out.println("observered by "+ serverName +": child node is :"+ str);
} } //查看临时节点的同步状态
public void observerChildData(String path) throws KeeperException, InterruptedException
{
if(operationCient==null)
{
System.out.println("operationCient=null");
return;
} List<String> childs=operationCient.getChilds(rootPath);
if(islog){
System.out.println("observered by "+ serverName +": childs len is :"+ childs.size());
}
for(String str : childs)
{
if(islog){
System.out.println("observered by "+ serverName +": child node is :"+ str+",data is :"+operationCient.getData(rootPath+"/"+str));
}
} }
public String getNowTime()
{
DateFormat format1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
return format1.format(new Date());
} }
zookeeper 应用开发的更多相关文章
- zookeeper[3] zookeeper API开发注意事项总结
如下是根据官方接口文档(http://zookeeper.apache.org/doc/r3.4.1/api/org/apache/zookeeper/ZooKeeper.html#register( ...
- zookeeper Eclipse 开发环境搭建及简单示例
一,下载Zookeeper安装包 从官方网站下载稳定版安装包后,解压. 其中ZK_HOME 为:D:\Program Files\zookeeper-3.4.9 二,启动Zookeeper Serve ...
- Zookeeper项目开发环境搭建(Eclipse\MyEclipse + Maven)
写在前面的话 可详细参考,一定得去看 HBase 开发环境搭建(Eclipse\MyEclipse + Maven) 我这里,相信,能看此博客的朋友,想必是有一定基础的了.我前期写了大量的基础性博文. ...
- 【分布式技术专题】「Zookeeper中间件」给大家学习一下Zookeeper的”开发伴侣”—Curator-Framework(基础篇)
CuratorFramework基本介绍 CuratorFramework是Netflix公司开源的一套Zookeeper客户端框架,它作为一款优秀的ZooKeeper客户端开源工具,主要提供了对客户 ...
- zookeeper+dubbo-admin开发dubbo应用
前面的章节中我们已经安装好了zookeeper,tomcat了.今天我们来实现一个完整的从dubbo消息产生到消费的完整流程. 1.dubbo api 2.dubbo consumer 消费者 3.d ...
- Zookeeper入门开发demo
package CreateGroup; import java.io.IOException; import java.util.List; import java.util.concurrent. ...
- 分布式服务协调技术zookeeper笔记
本文主要学习ZooKeeper的体系结构.节点类型.节点监听.常用命令等基础知识,最后还学习了ZooKeeper的高可用集群的搭建与测试.希望能给想快速掌握ZooKeeper的同学有所帮助. ZooK ...
- hadoop学习笔记:zookeeper学习(上)
在前面的文章里我多次提到zookeeper对于分布式系统开发的重要性,因此对zookeeper的学习是非常必要的.本篇博文主要是讲解zookeeper的安装和zookeeper的一些基本的应用,同时我 ...
- 基于ZooKeeper的分布式Session实现(转)
1. 认识ZooKeeper ZooKeeper—— “动物园管理员”.动物园里当然有好多的动物,游客可以根据动物园提供的向导图到不同的场馆观赏各种类型的动物,而不是像走在原始丛林里,心惊胆颤的被 ...
随机推荐
- Freemarker 浅析
今天分享一下一个模板语言的使用,它就是Freemarker,有点类似与前些日子做Python的Django中的模板语言,其实原理上都是相似的.所以这里就不对那些基础性的语法类的直至进行讲解了,就拿几个 ...
- 【IOS 开发】基本 UI 控件详解 (UIDatePicker | UIPickerView | UIStepper | UIWebView | UIToolBar )
转载注明出处 : http://blog.csdn.net/shulianghan/article/details/50348982 一. 日期选择器 (UIDatePicker) UIDatePic ...
- Storm并发机制详解
本文可作为 <<Storm-分布式实时计算模式>>一书1.4节的读书笔记 在Storm中,一个task就可以理解为在集群中某个节点上运行的一个spout或者bolt实例. 记住 ...
- UNIX网络编程——epoll的 et,lt关注点
epoll模型有两种工作模式,ET和LT两种模式下都有一些细节值得注意,以下是一些思考: 一.ET模式下 Q1:调用accept时,到底TCP完成队列里有多少个已经建立好的连接? 这 ...
- ubuntu opengl 开发
开发环境: eclipse,需要安装C++开发插件,在自带的源中查找安装C++开发工具包即可 下载安装gl库: sudo apt-get install libgl1-mesa-dev 下载安装glu ...
- 06 Activity显示跳转
<span style="font-size:18px;">package com.fmy.day8_29task; import com.fmy.day8_29tas ...
- SDK目录结构
android sdk里的各目录作用 AVD Manager.exe:虚拟机管理工具,用于建立和管理虚拟机. SDK Manager.exe:sdk管理工具,用于管理.下载sdk.sdk工具,能及扩展 ...
- Dynamics CRM2011/2013 删除个人视图
这里以2013为例,2011同理.个人视图的功能很人性化,可以设置自己常看数据列表形式而不会去影响别人,但创建容易怎么删除还真不一定能找得到地,具体见下方截图.
- cocos2dx 3.3 + QT5.3制作游戏编辑器
欢迎转载,但请注明本blog地址,谢谢_(:зゝ∠)_ http://www.cnblogs.com/marisa/p/4141862.html 主要参考: http://blog.csdn.net/ ...
- Java 中Log4j的使用详情
Log4j 真的很简单,简单到令人发指的地步.不是要记录日志吗?那就给你一个Log ,然后你用Log 来写东西就行了,先来一个完整类示例: package test; import org.apach ...