1、案例描述
这是一个从从zookeeper官网获取的简单案例。请先确保你已经安装好一个zookeeper机器环境,如果没有请参考我的文章《zookeeper入门》http://blog.csdn.net/koflance/article/details/78586235。
案例基本设计要求是,监听一个zookeeper的节点路径,比如/test,如果节点路径上保存的数据发生了变更,则将数据写入到指定的本地文件中,同时启动一个本地脚本命令,比如用cat将该本地文件读取出来,显示在终端。
基本步骤如下:
- 实例化一个zookeeper客户端,并将一个哨兵(watcher)注册到该节点下;
- 实例化一个节点数据监听器(datamointor),用异步方式(zk.exists)获取节点数据的变更状态;
- 实例化一个脚本执行器(Executor),并将其注册为数据监听器(datamointor)的观察者(listener);
- 数据监听器(datamointor)收到zk客户端的变更消息,立即用异步方式(zk.exists)获取节点数据,并判断是否变更(b != preData),如果变更,则通知观察者(listener);
- 脚本执行器收到datamointor的数据变更通知,立即将获取到的节点数据写入文件(filename),写入之后启用本地脚本任务process,将内容打印出来。
2、案例代码
- Executor 脚本执行器及zookeeper客户端和哨兵
package com.xxxx.xxxx.zookeeper;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import java.io.*;
/**
* 在指定的znode路径节点上,使用DataMonitor获取节点数据或状态变更情况。
* 这个类会观察指定znode节点并保存数据在该路径上,当znode存在时,启动指定的程序;当znode节点不存在时,关闭指定的程序。
*
* Created by wushiweijun on 2017/11/20.
*/
public class Executor implements Watcher, Runnable, DataMonitor.DataMonitorListener {
private final DataMonitor dm;
private final ZooKeeper zk;
private final String filename;
private final String[] exec;
/*需要执行命令的程序*/
private Process child;
public static void main(String[] args) {
args = "localhost:2181,localhost:2182,localhost:2183 /test /Users/wushiweijun/Documents/test/zookeeper/executor.txt cat /Users/wushiweijun/Documents/test/zookeeper/executor.txt".split(" ");
// if (args.length < 4) {
// System.err
// .println("USAGE: Executor hostPort znode filename program [args ...]");
// System.exit(2);
// }
String hostPort = args[0];
String znode = args[1];
String filename = args[2];
String exec[] = new String[args.length - 3];
System.arraycopy(args, 3, exec, 0, exec.length);
try {
new Executor(hostPort, znode, filename, exec).run();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
*
* @param hostPort 集群的host地址列表,多个用逗号分隔,例如host:port,host:port,host:port/app/a
* @param znode 访问的节点路径
*