目录
1.需求
某分布式系统中,主节点可以有多台,可以动态上下线,任意一台客户端都能实时感知 到主节点服务器的上下线。这里用客户端和服务端模拟。 (1)服务端:输入服务器hostname模拟上线,在zk集群创建节点,节点是临时节点,重启程序就表示下线了。 (2)客户端:监听zk集群的节点变化就知道服务器的上下线情况。2.需求分析
上线创建的节点在/servers下面
3.具体实现
( 1 )先在集群上创建 /servers 节点[zk: localhost:2181(CONNECTED) 10] create /servers "servers"
Created /servers
(2)在
Idea
中创建包名:
com.atguigu.zkcase1
(3)服务器端
代码
public class DistributeServer {
private String connectString = "hadoop102:2181,hadoop103:2181,hadoop104:2181";
private int sessionTimeout = 2000;
private ZooKeeper zk;
public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
DistributeServer server = new DistributeServer();
//1 获取zk连接
server.getConnect();
//2 注册服务器到zk集群
server.regist(args[0]);
//3 启动业务逻辑(sleep)
server.business();
}
private void business() throws InterruptedException {
Thread.sleep(Long.MAX_VALUE);
}
private void regist(String hostname) throws KeeperException, InterruptedException {
//因为上下线,因此节点是临时的,加-e
String create = zk.create("/servers/" + hostname, hostname.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
//打印上线信息
System.out.println(hostname + " is online");
}
private void getConnect() throws IOException {
zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
}
});
}
}
(4)客户端代码
public class DistributeClient {
private String connectString = "hadoop102:2181,hadoop103:2181,hadoop104:2181";
private int sessionTimeout = 2000;
private ZooKeeper zk;
public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
DistributeClient client = new DistributeClient();
//1 获取zk连接
client.getConnect();
//2 监听/servers下面子节点的增加和删除
client.getServerList();
//3 业务逻辑(sleep)
client.business();
}
private void business() throws InterruptedException {
Thread.sleep(Long.MAX_VALUE);
}
private void getServerList() throws KeeperException, InterruptedException {
List<String> children = zk.getChildren("/servers", true);
ArrayList<String> servers = new ArrayList<>();
for (String child : children) {
//路径进行拼接
//上面根目录已经监听了,这里就不监听了
//第三参数是状态
byte[] data = zk.getData("/servers/" + child, false, null);
servers.add(new String(data));
}
System.out.println(servers);
}
private void getConnect() throws IOException {
zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
try {
getServerList();
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
4.测试
1 )在 Linux 命令行上操作增加减少服务器 测试客户端代码 ( 1 )启动 DistributeClient 客户端 (2)在 hadoop102 上 zk 的客户端 /servers 目录上创建临时带序号节点[zk: localhost:2181(CONNECTED) 1] create -e -s
/servers/hadoop102 "hadoop102"
[zk: localhost:2181(CONNECTED) 2] create -e -s
/servers/hadoop103 "hadoop103"
(3)观察
Idea
控制台变化
[hadoop102, hadoop103]
(4)执行删除操作
[zk: localhost:2181(CONNECTED) 8] delete
/servers/hadoop1020000000000
(5)观察
Idea
控制台变化
[hadoop103]
2
)在
Idea
上操作增加减少服务器
(
1
)启动
DistributeClient
客户端(如果已经启动过,不需要重启)
(2)启动
DistributeServer
服务
①点击
Edit Configuration
②在弹出的窗口中(
Program arguments
)输入想启动的主机,例如,
hadoop102
③回到
DistributeServer
的
main
方 法 , 右 键 , 在 弹 出 的 窗 口 中 点 击
Run
“DistributeServer.main()”
④观察
DistributeServer
控制台,提示
hadoop103 is online
⑤观察
DistributeClient
控制台,输出节点信息,提示
hadoop103
已经上线