Zookeeper 应用案例
1、服务器上下线动态感知
1、需求描述
某分布式系统中,主节点可以有多台,可以动态上下线。任意一台客户端都能实时感知 到主节点服务器的上下线
2、设计思路
3、代码开发
服务器端处理:
package com.zookeeper.app.serverList;
import org.apache.zookeeper.CreateMode;
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;
/**
* 用来处理服务器上下线往zookeeper写入或者删除数据用的。
* 它就是我们抽象出来的一个台服务器,用于服务器上线
*/
public class ServerWorkServerStart {
private static final String connectString = "hadoop02:2181,hadoop03:2181,hadoop04:2181";
private static final int sessionTimeout = 4000;
// 上线的服务器列表的父节点
private static final String PARENT_NODE = "/servers";
// 上线服务器
private static final String server = "hadoop03";
private static final String SUB_NODE = server;
public static void main(String[] args) throws Exception {
// 拿zookeeper的请求链接
ZooKeeper zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent event) {
}
});
/**
* 为了在第一台服务器上线的时候找不到父节点,去先把这个父节点给创建出来
*/
Stat exists = zk.exists(PARENT_NODE, false);
if (exists == null) {
zk.create(PARENT_NODE, "servers_parent_node".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
// 拿到zookeeper链接之后,就往我们的父znode节点下去写入一台服务器的信息,写入
// 的znode类型是临时节点
zk.create(PARENT_NODE + "/" + SUB_NODE, server.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println(server + " is online。。。。。。。。。");
zk.close();
}
}
package com.zookeeper.app.serverList;
import org.apache.zookeeper.CreateMode;
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;
/**
* 用来处理服务器上下线往zookeeper写入或者删除数据用的。
* 它就是我们抽象出来的一个台服务器,用于服务器下线
*/
public class ServerWorkServerStop {
private static final String connectString = "hadoop02:2181,hadoop03:2181,hadoop04:2181";
private static final int sessionTimeout = 4000;
private static final String PARENT_NODE = "/servers";
private static final String server = "hadoop04";
public static void main(String[] args) throws Exception {
// 拿zookeeper的请求链接
ZooKeeper zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent event) {
}
});
/**
* 为了在第一台服务器上线的时候找不到父节点,去先把这个父节点给创建出来
*/
Stat exists = zk.exists(PARENT_NODE, false);
if (exists == null) {
zk.create(PARENT_NODE, "servers_parent_node".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
/**
* 服务器下线程序
*/
zk.delete(PARENT_NODE + "/" + server, -1);
zk.close();
}
}
客户端处理:
package com.zookeeper.app.serverList;
import java.util.ArrayList;
import java.util.List;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.ZooKeeper;
/**
* 这就是用户的客户端程序,用来监控服务器集群到底有哪些服务器在工作
*/
public class ServerWorkClient {
private static final String connectString = "hadoop02:2181,hadoop03:2181,hadoop04:2181";
private static final int sessionTimeout = 4000;
private static final String PARENT_NODE = "/servers";
static ZooKeeper zk = null;
public static void main(String[] args) throws Exception {
/**
* 1、拿zookeeper的服务器链接
*/
zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent event) {
String path = event.getPath();
EventType et = event.getType();
/**
* 收到监听通知的时候,就去查询servers节点下有哪些服务器在线
*/
if(path.equals(PARENT_NODE) && et == EventType.NodeChildrenChanged){
/**
* 2、获取父节点servers下有哪些子节点,并且把子节点的数据给拿出来
*/
List<String> hostList = getServerList();
// [hadoop01,hadoop02]
System.out.println(hostList);
}else{
System.out.println("当前事件跟我服务器动态上下线没有任何关系");
}
}
});
zk.getChildren(PARENT_NODE, true);
Thread.sleep(Long.MAX_VALUE);
zk.close();
}
/**
* 用来获取当前在线服务器列表
*/
public static List<String> getServerList(){
List<String> hostList = new ArrayList<String>();
try {
// 这句话是为了获取servers节点下的子节点
List<String> children = zk.getChildren(PARENT_NODE, true);
for(String znode: children){
byte[] data = zk.getData(PARENT_NODE+"/"+znode,false, null);
hostList.add(new String(data));
}
} catch (Exception e) {
e.printStackTrace();
}
return hostList;
}
}