1.分别用java写一个客户端和服务端。
2.开启客户端查看服务器状态。
3.开启关闭服务端来查看客户端是否监听到变化。
以下是实验结果:
这是客户端,可以看到客户端在更新服务器的上下线状态。
接下开直接贴代码:
服务端代码:
package zookeeper_zkdistributed;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
public class DistributedServer {
private static final String connectString ="node1:2181,node2:2181,node3:2181";
private static final int sessionTimeout=2000; //设置超时时间为2秒
ZooKeeper zk=null;
private static final String parentNode="/servers";
public static void main(String[] args) throws Exception {
//1.获取zk连接
DistributedServer server = new DistributedServer();
server.getConnect();
//2.利用zk连接注册服务信息
server.registerServer(args[0]);
//3.启动业务功能
server.handleBussiness(args[0]);
}
/**
* 创建zk集群的客户端连接
* @throws Exception
*/
public void getConnect() throws Exception {
zk=new ZooKeeper(connectString, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent event) {
// 收到事件通知后的回调函数,事件处理逻辑
//事件类型和事件路径(节点)
System.out.println(event.getType()+"-------"+event.getPath());
//可实现反复监听
try {
zk.getChildren("/", true);
} catch (Exception e) {
e.printStackTrace();
}
}
} );
}
/**
* 向zk集群注册服务器信息
* @param hostname 服务器主机名
* @throws Exception
*/
public void registerServer(String hostname) throws Exception{
String create = zk.create(parentNode+"/server", hostname.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println(hostname+" is online...."+ create);
}
/**
* 业务功能
* @param hostname 服务器主机名
* @throws Exception
*/
public void handleBussiness(String hostname) throws Exception {
System.out.println(hostname+"start working....");
Thread.sleep(Long.MAX_VALUE);
}
}
客户端代码:
package zookeeper_zkdistributed;
import java.util.ArrayList;
import java.util.List;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
public class DistributedClient {
private static final String connectString ="node1:2181,node2:2181,node3:2181";
private static final int sessionTimeout=2000; //设置超时时间为2秒
private static final String parentNode="/servers";
private volatile List<String> serverList;
private ZooKeeper zk=null;
public static void main(String[] args) throws Exception {
//获取zk连接
DistributedClient client = new DistributedClient();
client.getConnect();
//获取servers的子节点信息(并监听),从中获取服务器信息列表
client.getServerList();//回调process方法
//业务线程启动
client.handleBussiness();
}
/**
* 创建zk集群的客户端连接
* @throws Exception
*/
public void getConnect() throws Exception {
zk=new ZooKeeper(connectString, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent event) {
// 收到事件通知后的回调函数,事件处理逻辑
try {
//重新更新服务器列表,并且注册了监听
getServerList();
} catch (Exception e) {
e.printStackTrace();
}
}
} );
}
/**
* 获取服务器信息链表
* @throws Exception
*/
public void getServerList() throws Exception {
//获取服务器子节点信息,并且对父节点进行监听
List<String> children = zk.getChildren(parentNode, true);
//先创建一个局部的list来存放信息
ArrayList<String> servers = new ArrayList<String>();
for (String child: children) {
//child只是子节点的节点名,getData才是数据内容
byte[] data = zk.getData(parentNode+"/"+child,false, null);
servers.add(new String(data));
}
//把servers赋值给成员变量serverList,提供给各业务进程使用
serverList=servers;
//打印列表
System.out.println(serverList);
}
/**
* 业务功能
* @param hostname 服务器主机名
* @throws Exception
*/
public void handleBussiness() throws Exception {
System.out.println("client start working....");
Thread.sleep(Long.MAX_VALUE);
}
}
以上代码导出为可执行的.jar文件,即可在window的命令行中测试。