因为每台服务器都可以安装zookeeper,并且只要在一台服务器上进行登陆客户端,便可以对所有节点情况进行查看,那么可以利用这一特性,可以有效的监控集群中服务器情况
每台服务器都创建维护一个瞬时节点,这样一旦某台服务器出现了故障,那么其创建维护的瞬时节点就会消失,此时在动态的列表中,出现故障的服务器维护的节点就会不存在,这样,便可以有效监控服务器的状态.
因为zookeeper无法监听子节点数据的变化,但是可以监听子节点变化,所以把所有服务器都想成节点,去创建瞬时序列节点,以实现动态列表
编写创建动态节点和储存服务器名称的操作类
import org.apache.zookeeper.*;
public class CreateServer {
//创建类的构造方法,Servername,服务器名称,用于被当成数据储存于临时子节点下
public CreateServer(String servername) throws Exception{
//启动创建和监听的动态列表
Listener(servername);
//启动休眠操作方法
sleepMethod();
}
//创建休眠操作方法
public void sleepMethod() throws Exception{
//输出语句告诉使用者,程序已被启动
System.out.println("The program is started");
Thread.sleep(Long.MAX_VALUE);
}
//创建监听和创建临时节点的方法
public void Listener(String ServerName) throws Exception{
//主节点路径,此路径下,存放各服务器的临时有序节点以实现动态列表
String groupNode="/servers";
//从节点路径,从节点是有序临时节点,用于随session消失而消失,以观察服务器是否正常运行中
String subNode="/servers/server-";
//授权账户
String auth="sheng:123";
//服务器IP地址
String connectString="192.168.73.134,192.777.163.62";
int sessionTimeout=2000;
ZooKeeper zooKeeper=new ZooKeeper(connectString, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent event) {
System.out.println("New server joining STAT:"+event.getState()+event.getPath());
}
});
if (zooKeeper.exists(groupNode,false)==null){
//父节点是持久节点
zooKeeper.create(groupNode,"allservers".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
if (zooKeeper.exists(subNode,true)==null){
//创建临时序列化子节点
zooKeeper.create(subNode,ServerName.getBytes(),ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL_SEQUENTIAL);
}
}
}
编写主方法类
//此程序主程序类,用于启动程序
public class MainMethod {
public static void main(String[] args) throws Exception {
//说明没有传递参数
if (args.length!=1){
System.out.println("There must be parameters");
//退出系统
System.exit(1);
}
//启动操作类
new CreateServer(args[0]);
}
}
使用开发工具IDEA或Eclipse将项目打包为可执行的jar包,并且上传到服务器
上传到Liunx服务器(博主使用Ubuntun系统进行开发,仅供参考)
在服务器执行刚才上传的Jar,用于动态列表的生成
会提示创建成功
登陆zookeeper客户端查看新创建的临时节点
查看节点下储存的服务器名称
关闭服务器检测临时节点是否会消失
成功!!!
客户端jar包主要想达到的目的在于可以实时查看动态列表的变化,以便于实时知道服务器集群的运行情况
监听代码类
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
public class ListenServer {
//主节点路径,此路径下,存放各服务器的临时有序节点以实现动态列表
String groupNode="/servers";
//服务器IP地址
String connectString="192.333.674.234,192.168.99.143";
int sessionTimeout=2000;
public ZooKeeper zooKeeper=null;
public ListenServer() throws Exception{
//启动创建和监听的动态列表
getConnection();
getChildren();
//获取子节点信息
//睡眠
sleepMethod();
}
//创建休眠操作方法
public void sleepMethod() throws Exception{
//输出语句告诉使用者,程序已被启动
System.out.println("The program is started");
Thread.sleep(Long.MAX_VALUE);
}
//创建连接
public void getConnection() throws Exception{
zooKeeper=new ZooKeeper(connectString, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent event) {
//如果子节点发生了改变
if (event.getType()== Event.EventType.NodeChildrenChanged){
try {
ListenServer.this.getChildren();
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
if (zooKeeper.exists(groupNode,false)==null){
//父节点是持久节点
zooKeeper.create(groupNode,"allservers".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
}
//获取子节点详细信息的方法
public void getChildren() throws Exception{
//创建一个Set集合用于储存当前子节点的数据
Set<String> childrenNode=new HashSet<String>();
//获取根节点下所有临时子节点的数据
List<String> childrenNodes=zooKeeper.getChildren(groupNode,true);
//迭代输出子节点名称
Iterator<String> iter=childrenNodes.iterator();
while (iter.hasNext()){
//通过子节点名称循环找到这些子节点下储存的数据
Stat stat=new Stat();
//获取子节点数据并转化为数组
String node=new String(zooKeeper.getData(groupNode+"/"+iter.next(),true,stat));
//放入集合之中
childrenNode.add(node);
}
System.out.println("节点数据更新,详情如下表"+childrenNode);
}
}
主方法类
public class MainMethod {
public static void main(String[] args) throws Exception {
new ListenServer();
}
}
同样利用开发工具打包成可用jar
插入节点测试程序是否会输出更新结果
发现程序已经提醒插入了data为zkserver-a的节点
成功!!!