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

3.具体实现
(0)先在集群上创建/servers节点:
[zk: localhost:2181(CONNECTED) 10] create /servers "servers" Created /servers
(1)服务器端向Zookeeper注册代码:
import org.apache.zookeeper.*;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
public class DistributeServer {
public static void main(@NotNull String[] args) throws IOException, KeeperException, InterruptedException {
DistributeServer server = new DistributeServer();
// 思路:先写大框架!在考虑细节
// 1.连接zookeeper集群
server.getConnect();
// 2.注册节点
server.regist(args[0]);
// 3.业务逻辑处理
server.business();
}
private void business() throws InterruptedException {
// 睡眠,保证进程不结束
Thread.sleep(Long.MAX_VALUE);
}
private void regist(String hostname) throws KeeperException, InterruptedException {
// 由于每次注册只调用下面这一个方法,故设置CreateMode时只能设置临时带序号的类型
zkClient.create("/servers/server",hostname.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println(hostname + " is online !");
}
private String connectString = "hadoop102:2181,hadoop103:2181,hadoop104:2181";
private int sessionTimeout = 2000;
private ZooKeeper zkClient;//客户端对象
private void getConnect() throws IOException {
zkClient = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
public void process(WatchedEvent event) {
}
});
}
}

(2)客户端代码
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class DistributeClient {
private String connectString = "hadoop102:2181,hadoop103:2181,hadoop104:2181";
private int sessionTimeout = 2000;
private ZooKeeper zkClient;//客户端对象
public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
DistributeClient client = new DistributeClient();
// 1.获取zookeeper集群连接
client.getConnect();
// 2. 注册监听
client.getChildren();
// 3.业务逻辑处理
client.business();
}
private void business() throws InterruptedException {
Thread.sleep(Long.MAX_VALUE);
}
private void getChildren() throws KeeperException, InterruptedException {
// 监听/servers 启动监听之后会进入new Watcher()的process方法中
List<String> children = zkClient.getChildren("/servers", true);
// 存储服务器节点主机的名称,放在集合里
ArrayList<String> hosts = new ArrayList<String>();;
for (String child :
children) {
// 拼接可得要获得的数据目的地
byte[] data = zkClient.getData("/servers/" + child, false, null);
hosts.add(new String(data));
}
// 将所有在线主机名称打印到控制台
System.out.println(hosts);
}
private void getConnect() throws IOException {
zkClient = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
public void process(WatchedEvent event) {
System.out.println("启用的监听!");
// 如果不将下面的代码放在此处,那么监听只会执行一次
try {
// 为了动态监听
getChildren();
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
要记得在运行时候main中args[ ]要事先配置哦!