需求
某分布式系统中,主节点可以有多台,可以动态上下线,任意一台客户端都能实时感知到主节点服务器的上下线。
需求分析

具体实现
0)先在集群上创建/servers节点
$ create /servers "servers"
1)服务器端向Zookeeper注册代码
public class DistributeServer {
public static void main(String[] args) throws Exception {
// 1 获取zk连接
DistributeServer server = new DistributeServer();
server.getConnect();
// 2 注冊节点
server.regist(args[0]);
// 3 业务逻辑启动
server.business();
}
private static String connectString = "hadoop102:2181,hadoop103:2181,hadoop104:2181";
private static int sessionTimeout = 2000;
private ZooKeeper zkClient;
public void getConnect() throws IOException {
zkClient = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent event) {
}
});
}
public void business() throws Exception {
Thread.sleep(Long.MAX_VALUE);
}
public void regist(String hostname) throws KeeperException, InterruptedException {
String path = zkClient.create("/servers/server", hostname.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println(hostname + " is online");
}
}
2)客户端代码
public class DistributeClient {
public static void main(String[] args) throws Exception {
// 1 获取zk连接
DistributeClient client = new DistributeClient();
client.getConnect();
// 2 注冊监听
client.getChildren();
// 3 业务逻辑处理
client.business();
}
private static String connectString = "hadoop102:2181,hadoop103:2181,hadoop104:2181";
private static int sessionTimeout = 2000;
private ZooKeeper zkClient;
public void getConnect() throws IOException {
zkClient = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent event) {
try {
getChildren();
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
public void business() throws Exception {
Thread.sleep(Long.MAX_VALUE);
}
public void getChildren() throws KeeperException, InterruptedException {
List<String> children = zkClient.getChildren("/servers", true);
//存储服务器节点主机名称集合
ArrayList<String> hosts = new ArrayList<>();
for (String child : children) {
byte[] data = zkClient.getData("/servers/" + child, false, null);
hosts.add(new String(data));
}
//将所有在线主机名称打印到控制台
System.out.println(hosts);
}
}
网友评论