服务器端:监听zk上父节点的子节点变化
package monitor;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
/**
* 监听客户端的上下线
* @author lisg
*
*/
public class ServerMonitor {
public static final String HOSTS = "vm1";
private ZooKeeper zk = null; public static final String PARENT_PATH = "/monitor"; private static int client_count = 0;
public ServerMonitor() {
final CountDownLatch cdl = new CountDownLatch(1);
try {
zk = new ZooKeeper(HOSTS, 5000, new Watcher() {
@Override
public void process(WatchedEvent event) {
if(KeeperState.SyncConnected.equals(event.getState())) {
cdl.countDown();
}
}
}); cdl.await(); //创建父节点
if(zk.exists(PARENT_PATH, false) == null) {
zk.create(PARENT_PATH,
"".getBytes(),
ZooDefs.Ids.OPEN_ACL_UNSAFE,
CreateMode.PERSISTENT);
}
} catch (Exception e) {
e.printStackTrace();
}
} public void run() {
try {
zk.getChildren(PARENT_PATH, new ClientChangeWatcher());
} catch (Exception e) {
e.printStackTrace();
}
} class ClientChangeWatcher implements Watcher {
@Override
public void process(WatchedEvent event) {
try {
if(Event.EventType.NodeChildrenChanged.equals(event.getType())) {
//获取子节点,同时注册监听
final List<String> children = zk.getChildren(PARENT_PATH, this);
if(client_count > children.size()) {
System.out.println("有客户端下线");
} else {
System.out.println("有客户端上线");
}
client_count = children.size();
}
} catch (Exception e) {
e.printStackTrace();
}
}
} public static void main(String[] args) {
new ServerMonitor().run(); try {
TimeUnit.DAYS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
客户端:上线的时候在父节点上创建短暂的子节点
package monitor;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
/**
* 客户端
* 上线的时候在zk上创建一个短暂的子节点
* @author lisg
*
*/
public class Client { public static final String CLIENT_PATH_PREFIX = "cli-";
public static void main(String[] args) {
final CountDownLatch cdl = new CountDownLatch(1);
try {
ZooKeeper zk = new ZooKeeper(ServerMonitor.HOSTS, 5000, new Watcher() {
@Override
public void process(WatchedEvent event) {
if(KeeperState.SyncConnected.equals(event.getState())) {
cdl.countDown();
}
}
}); cdl.await(); //创建父节点
zk.create(ServerMonitor.PARENT_PATH + "/" + CLIENT_PATH_PREFIX,
"".getBytes(),
Ids.OPEN_ACL_UNSAFE,
CreateMode.EPHEMERAL_SEQUENTIAL); TimeUnit.SECONDS.sleep(5);
zk.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}