分析:
对于zookeeper集群而言服务器端和客户端都是它的客户端
只是服务器端对于此案列而言充当了写的功能,客户端充当了读的功能
步骤:
服务器端:
1连接到zookeeper集群
2实现每台服务器在/servers/下创建一个临时节点(节点名称和内容都是该服务器的主机名)
客户端:
1连接到zookeeper集群
2监视/servers/下的节点变化,并打印/servers/下节点的内容,就知道哪些服务器还在线上(因为创建的是临时节点,当服务器下线后/servers/下相应的节点会删除)
自己对于代码中的一些思考:
1在zookeeper里面的监视器添加后只能执行一次,所以怎么能永久监听呢?
在process里面监听一次后再次设置一次监听就好(也就是getServerList()函数中的zk.getChildren(parentNode, true)),以此循环下去,就能实现一直监听
2为什么客户端和服务器端都要Thread.sleep(Long.MAX_VALUE)?
因为不设置的话主程序里面的代码一下就跑完了,实现不了一直监听的作用,Thread.sleep(Long.MAX_VALUE)就让程序进行睡眠,Thread.sleep(Long.MAX_VALUE)之前的代码中监听器是可以继续工作的
servers代码:
import org.apache.zookeeper.*;
import java.io.IOException;
public class Servers {
private static String connectString="hadoop200:2181,hadoop201:2181,hadoop202:2181";
private static int sessionTimeout = 2000;
private ZooKeeper zk = null;
private String parentNode = "/servers";
// 创建到 zk 的客户端连接
public void getConnect() throws IOException {
zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
public void process(WatchedEvent watchedEvent) {
}
});
}
// 注册服务器
public void registServer(String hostname) throws Exception {
String create = zk.create("/servers/" + hostname, hostname.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println(hostname + " is online " + create);
}
// 业务功能
public void business(String hostname) throws Exception {
System.out.println(hostname + " is working ...");
Thread.sleep(Long.MAX_VALUE);
}
public static void main(String[] args) throws Exception {
// 1 获取 zk 连接
Servers server = new Servers();
server.getConnect();
// 2 利用 zk 连接注册服务器信息
server.registServer(args[0]);
// 3 启动业务功能
server.business(args[0]);
}
}
Client代码:
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 Client {
private static String connectString="hadoop200:2181,hadoop201:2181,hadoop202:2181";
private static int sessionTimeout = 2000;
private ZooKeeper zk = null;
private String parentNode = "/servers";
// 创建到 zk 的客户端连接
public void getConnect() throws IOException {
zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
public void process(WatchedEvent event) {
// 再次启动监听
try {
getServerList();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
// 获取服务器列表信息
public void getServerList() throws Exception {
// 1 获取服务器 子节点信息,并且对父节点进行监听
List<String> children = zk.getChildren(parentNode, true);
// 2 存储服务器信息列表
ArrayList<String> servers = new ArrayList<String>();
// 3 遍历所有节点,获取节点中的主机名称信息
for (String child : children) {
byte[] data = zk.getData(parentNode + "/" + child,false, null);
servers.add(new String(data));
}
// 4 打印服务器列表信息
System.out.println(servers);
}
// 业务功能
public void business() throws Exception{
System.out.println("client is working ...");
Thread.sleep(Long.MAX_VALUE);
}
public static void main(String[] args) throws Exception {
// 1 获取 zk 连接
Client client = new Client();
client.getConnect();
// 2 获取 servers 的子节点信息,从中获取服务器信息列表
client.getServerList();
// 3 业务进程启动
client.business();
}
}