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—— “动物园管理员”.动物园里当然有好多的动物,游客可以根据动物园提供的向导图到不同的场馆观赏各种类型的动物,而不是像走在原始丛林里,心惊胆颤的被 ...
随机推荐
- Google Dremel数据模型详解(上)
首先简单介绍一下Dremel是什么,能解决什么问题.第二部分着重讲Dremel的数据模型,即数据结构.第三部分将谈一下在此数据结构上设计的算法. 1 起源 Dremel的数据模型起源于分布式系统的应用 ...
- 第一行代码阅读笔记---详解分析第一个Android程序
以下是我根据作者的思路,创建的第一个Android应用程序,由于工具强大,代码都自动生成了,如下: package com.example.first_app; import android.os.B ...
- 01_数据库连接池,数据源,ResultSetMetaData,jdbc优化
一.数据库连接池 1. 什么是连接池 传统的开发模式下,Servlet处理用户的请求,找Dao查询数据,dao会创建与数据库之间的连接,完成数据查询后会关闭数据库的链接. 这样的方式会导致用户每 ...
- iOS开发之*.a静态库注意事项
以*.a静态库的形式引入工程的(比如:libUploadLib.a),*.a里面的class有category形式实现时,除了在工程Target的 Build Phases里面的 Link Binar ...
- mysql数据库连接池使用(三)数据库元数据信息反射数据库获取数据库信息
1.1. mysql数据库连接池使用(三)数据库元数据信息反射数据库获取数据库信息 有时候我们想要获取到数据库的基本信息,当前程序连接的那个数据库,数据库的版本信息,数据库中有哪些表,表中都有什么字段 ...
- android GifView分享
gif图动画在android中还是比较常用的,比如像新浪微博中,有很多gif图片,而且展示非常好,所以我也想弄一个.经过我多方的搜索资料和整理,终于弄出来了,其实github上有很多开源的gif的展示 ...
- Gem/Bundle/Rvm
做过Ruby项目的人可能有过我一样的感受,rubygems.org在中国的访问太慢了,每次我们bundle install都要等老长时间,而我们通过浏览器去下载对应的gems文件时却速度刷刷的... ...
- 03 SeekBar 音频播放拖拽进度条
八, SeekBar 音频播放拖拽进度条 > android:progress="40" 第一进度 and ...
- java设计模式---备忘录模式
一.引子 俗话说:世上难买后悔药.所以凡事讲究个"三思而后行",但总常见有人做"痛心疾首"状:当初我要是--.如果真的有<大话西游>中能时光倒流的& ...
- bootmgr解压缩
主要参考以下两个文章: 1. http://bbs.wuyou.com/forum.php?mod=viewthread&tid=211314 2. http://reboot.pro/f ...