由于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 应用开发的更多相关文章

  1. zookeeper[3] zookeeper API开发注意事项总结

    如下是根据官方接口文档(http://zookeeper.apache.org/doc/r3.4.1/api/org/apache/zookeeper/ZooKeeper.html#register( ...

  2. zookeeper Eclipse 开发环境搭建及简单示例

    一,下载Zookeeper安装包 从官方网站下载稳定版安装包后,解压. 其中ZK_HOME 为:D:\Program Files\zookeeper-3.4.9 二,启动Zookeeper Serve ...

  3. Zookeeper项目开发环境搭建(Eclipse\MyEclipse + Maven)

    写在前面的话 可详细参考,一定得去看 HBase 开发环境搭建(Eclipse\MyEclipse + Maven) 我这里,相信,能看此博客的朋友,想必是有一定基础的了.我前期写了大量的基础性博文. ...

  4. 【分布式技术专题】「Zookeeper中间件」给大家学习一下Zookeeper的”开发伴侣”—Curator-Framework(基础篇)

    CuratorFramework基本介绍 CuratorFramework是Netflix公司开源的一套Zookeeper客户端框架,它作为一款优秀的ZooKeeper客户端开源工具,主要提供了对客户 ...

  5. zookeeper+dubbo-admin开发dubbo应用

    前面的章节中我们已经安装好了zookeeper,tomcat了.今天我们来实现一个完整的从dubbo消息产生到消费的完整流程. 1.dubbo api 2.dubbo consumer 消费者 3.d ...

  6. Zookeeper入门开发demo

    package CreateGroup; import java.io.IOException; import java.util.List; import java.util.concurrent. ...

  7. 分布式服务协调技术zookeeper笔记

    本文主要学习ZooKeeper的体系结构.节点类型.节点监听.常用命令等基础知识,最后还学习了ZooKeeper的高可用集群的搭建与测试.希望能给想快速掌握ZooKeeper的同学有所帮助. ZooK ...

  8. hadoop学习笔记:zookeeper学习(上)

    在前面的文章里我多次提到zookeeper对于分布式系统开发的重要性,因此对zookeeper的学习是非常必要的.本篇博文主要是讲解zookeeper的安装和zookeeper的一些基本的应用,同时我 ...

  9. 基于ZooKeeper的分布式Session实现(转)

    1.   认识ZooKeeper ZooKeeper—— “动物园管理员”.动物园里当然有好多的动物,游客可以根据动物园提供的向导图到不同的场馆观赏各种类型的动物,而不是像走在原始丛林里,心惊胆颤的被 ...

随机推荐

  1. Android加速度传感器

    Android加速度传感器 效果图 手机平放桌面的两张截屏,数据一直在刷新 源码 下载地址(Android Studio工程):http://download.csdn.net/detail/q487 ...

  2. Mac 下安装node.js

    Node.js 简介 Node.js 是一个用Chrome's V8 JavaScript engine 构建的 JavaScript 运行时框架.Node.js 使用事件驱动.非阻塞式 I/O 模块 ...

  3. 关于React Native 安卓首屏白屏优化

    问题描述 在android中,当点击某个rn模块的入口按钮,弹出rn的activity到rn的页面展现出来的过程中,会有很明显的白屏现象,不同的机型不同(cpu好的白屏时间短),大概1s到2s的时间. ...

  4. Linux下如何阅读开源项目

    标签(空格分隔): code SLAM是一个大型的项目,而且通常都是基于linux平台的.对于大部分没有linux经验的人来说,如何在linux下拥有vs代码阅读体验就非常重要了.这篇博客就简答的介绍 ...

  5. 7.0、Android Studio命令行工具

    命令行工具分成SDK工具和平台工具. SDK工具 SDK工具跟随SDK安装包安装并随时更新. Virtual Device 工具 1. Android Virtual Device Manager 提 ...

  6. Dynamics CRM2013/2015 插件注册工具登录后无法显示assembly列表问题的解决办法二

    本篇接前面的一篇博文:http://blog.csdn.net/vic0228/article/details/47079717,前篇提供了一种解决方案,将本机系统的语言切换成英文即可,今天再来介绍第 ...

  7. 查看某一职责下对应的菜单&功能&请求

    查看菜单&功能 SELECT res.RESPONSIBILITY_NAME 职责名称, menu.MENU_NAME 菜单编码, menu.USER_MENU_NAME 菜单名称, func ...

  8. android横竖屏切换activity生命周期变化

    1.新建一个Activity,并把各个生命周期打印出来 2.运行Activity,得到如下信息 onCreate--> onStart--> onResume--> 3.按crtl+ ...

  9. FFmpeg示例程序合集-Git批量获取脚本

    此前做了一系列有关FFmpeg的示例程序,组成了<FFmpeg示例程序合集>,其中包含了如下项目:simplest ffmpeg player:                  最简单的 ...

  10. Android开发学习之路--Activity之四种启动模式

    后天终于可以回家了,马上就要过年了,趁着年底打酱油的模式,就多学习学习,然后记录记录吧.关于Activity已经学习了七七八八了,还有就是Activity的四种启动模式了,它们分别为,standard ...