ZooKeeper的应用--服务器上下线动态感知

(一)需求描述
某分布式系统中,主节点可以有多台,可以动态上下线。任意一台客户端都能实时感知
到主节点服务器的上下线
(二)设计思路
1、设计服务器端存入服务器上线,下线的信息,比如都写入到 servers 节点下
2、设计客户端监听该 servers 节点,获取该服务器集群的在线服务器列表
3、服务器一上线,就往 zookeeper 文件系统中的一个统一的节点比如 servers 下写入一个临
时节点,记录下服务器的信息(思考,该节点最好采用什么类型的节点?)
4、服务器一下线,则删除 servers 节点下的该服务器的信息,则客户端因为监听了该节点的
数据变化,所以将第一时间得知服务器的在线状态
(三)代码开发
服务器端处理:

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;
/**
*服务器端处理
*@author Lv_Hulk
* 用来模拟服务器的动态上线下线
* 总体思路就是服务器上线就上 zookeeper 集群创建一个临时节点,然后监听了该数据节
点的个数变化的客户端都收到通知
* 下线,则该临时节点自动删除,监听了该数据节点的个数变化的客户端也都收到通知
*/
public class DistributeServer {
private static final String connectStr = "hadoop02:2181,hadoop03:2181,hadoop04:2181";
private static final int sessionTimeout = 4000;
private static final String PARENT_NODE = "/server";
static ZooKeeper zk = null;
public static void main(String[] args) throws Exception {
DistributeServer distributeServer = new DistributeServer();
distributeServer.getZookeeperConnect();
distributeServer.registeServer("hadoop03");
Thread.sleep(Long.MAX_VALUE);
}
/**
* 拿到 zookeeper 进群的链接
*/
public void getZookeeperConnect() throws Exception {
zk = new ZooKeeper(connectStr, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent event) {
}
});
}
/**
* 服务器上线就注册,掉线就自动删除,所以创建的是临时顺序节点
*/
public void registeServer(String hostname) throws Exception{
Stat exists = zk.exists(PARENT_NODE, false);
if(exists == null){
zk.create(PARENT_NODE,"server_parent_node".getBytes(),Ids.OPEN_ACL_UNSAFE, 
CreateMode.PERSISTENT);
}
zk.create(PARENT_NODE+"/"+hostname, hostname.getBytes(), Ids.OPEN_ACL_UNSAFE, 
CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println(hostname+" is online, start working......");
}
}

客户端处理:

import java.util.ArrayList;
import java.util.List;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
/**
*客户端处理
*@author Lv_Hulk
* 用来模拟用户端的操作:连上 zookeeper 进群,实时获取服务器动态上下线的节点信息
* 总体思路就是每次该 server 节点下有增加或者减少节点数,我就打印出来该 server 节点
下的所有节点
*/
public class DistributeClient {
private static final String connectStr = "hadoop02:2181,hadoop03:2181,hadoop04:2181";
private static final int sessionTimeout = 4000;
private static final String PARENT_NODE = "/server";
static ZooKeeper zk = null;
public static void main(String[] args) throws Exception {
DistributeClient dc = new DistributeClient();
dc.getZookeeperConnect();
Thread.sleep(Long.MAX_VALUE);
}
/**
* 拿到 zookeeper 进群的链接
*/
public void getZookeeperConnect() throws Exception {
zk = new ZooKeeper(connectStr, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent event) {
try {
// 获取父节点 server 节点下所有子节点,即是所有正上线服务的服
务器节点
List<String> children = zk.getChildren(PARENT_NODE, true);
List<String> servers = new ArrayList<String>();
for(String child: children){
// 取出每个节点的数据,放入到 list 里
String server = new String(zk.getData(PARENT_NODE+"/"+child, 
false, null), "UTF-8");
servers.add(server);
}
// 打印 list 里面的元素
System.out.println(servers);
} catch (Exception e) {
e.printStackTrace();
}
}
});
System.out.println("Client is online, start Working......");
}
}

猜你喜欢

转载自blog.csdn.net/lv_hulk/article/details/88572568