package com ;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
public class ZKServer implements Watcher{
public static void main(String[] args) throws Exception {
new ZKServer();
}
private final long delay= 2*1000l;
private final long period= 5*1000l;
private final String connectStr ="192.168.8.192:2181,192.168.8.135:2181,192.168.8.136:2181";
private final int sessionTimeout = 3000;
private final long zkCreateWaitTime = 30;
private ZooKeeper zkClient;
private CountDownLatch cdl= new CountDownLatch(1);
private final String parentPath="/servers";
//充當redis
private Map<String, Object> map = new LinkedHashMap<>(16);
String treeStr = null;
public ZKServer(){
createZkClient();
}
/**
* 添加一個節點
* @param hostname
*/
private void regist(String hostname){
String path = null;
try {
String node= parentPath+"/server";
if(zkClient.exists(node, false) !=null){
System.out.println("node "+node+" 已存在");
return ;
}
path = zkClient.create(node, hostname.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.err.println("node add "+path+" sussess info "+hostname);
}
/**
* 定時刷新緩存
*/
private void cacheStatusChecker(){
Timer rTimer =new Timer();
rTimer.schedule(task, delay, period);
}
private TimerTask task= new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
reloadCache();
}
};
private void reloadCache(){
if(null == zkClient && !zkClient.getState().isConnected())
return;
getChlidren();
};
private void getChlidren() {
getChlidren(parentPath);
// getChlidrenTree(parentPath);
}
/**
* 遞歸獲取節點信息
*/
private void getChlidren(String path) {
try {
if(path.equals(parentPath)){
byte[] data = zkClient.getData(path, false, null);
map.put(path, new String(data));
}
List<String> children = zkClient.getChildren(path, true);
if(children.isEmpty() || children.size()==0){
return ;
}
for (String child : children) {
String key = path+"/"+child;
byte[] data = zkClient.getData(key, false, null);
map.put(key, new String(data));
getChlidren(key);
}
} catch ( Exception e) {
// TODO Auto-generated catch block
System.err.println("獲取節點信息異常");
}
System.err.println("reloadCache : "+map.toString() );
}
/**
* 樹形數據
* @param path
*/
private void getChlidrenTree(String path) {
try {
if(path.equals(parentPath)){
JSONObject j = new JSONObject();
byte[] data = zkClient.getData(path, false, null);
j.put("path", path);
j.put("data", new String(data));
j.put("node", nodeBinning(path));
treeStr = j.toJSONString();
}else{
treeStr = nodeBinning(path);
}
} catch ( Exception e) {
// TODO Auto-generated catch block
System.err.println("獲取節點信息異常");
}
System.err.println("reloadCache : " + treeStr);
}
private String nodeBinning(String path) throws KeeperException, InterruptedException{
List<String> children = zkClient.getChildren(path, true);
JSONArray ja = new JSONArray();
for (String child : children) {
JSONObject j = new JSONObject();
String key = path+"/"+child;
byte[] data = zkClient.getData(key, false, null);
j.put("path", key);
j.put("data", new String(data));
j.put("node", nodeBinning(key));
ja.add(j);
}
return ja.toJSONString();
}
/**
* 創建zk連接
* @return
*/
private boolean createZkClient(){
try {
zkClient = new ZooKeeper(connectStr , sessionTimeout , this);
} catch (IOException e1) {
// TODO Auto-generated catch block
System.out.println(" zookeeper 連接異常" +connectStr +" err : " +e1);
//e1.printStackTrace();
}
cdl= new CountDownLatch(1);
try {
cdl.await(zkCreateWaitTime, TimeUnit.SECONDS);
} catch (Throwable e) {
// TODO Auto-generated catch block
System.out.println("等待連接時出現異常"+" err : " +e);
}
if(zkClient!=null){
try {
if(zkClient.exists(parentPath, false) !=null){
regist("123") ;
cacheStatusChecker();
return true;
}
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("zookeeper 客戶端異常 err : " +e);
}
}
return false;
}
/**
* 監聽回調
*/
@Override
public void process(WatchedEvent event) {
// TODO Auto-generated method stub
String path = event.getPath();
if (event.getState() == KeeperState.Expired){
System.out.println("session超時,zookeeper服務器連接失敗");
createZkClient();
}else if((event.getState() == KeeperState.SyncConnected)||
event.getState() == KeeperState.ConnectedReadOnly){
System.out.println("zookeeper已連接成功");
cdl.countDown();//連接成功後,主線程開始執行
// try {
// Thread.sleep(10000);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// System.out.println("Thread.sleep(10000) " + e);
// }
if (event.getType() == EventType.NodeCreated) {
System.out.println("zookeeper有新節點創建" + event.getPath());
}
if (event.getType() == EventType.NodeDataChanged) {
System.out.println("zookeeper有節點數據變化" + event.getPath());
}
if (event.getType() == EventType.NodeDeleted) {
System.out.println("zookeeper有節點被刪除" + event.getPath());
}
if (event.getType() == EventType.NodeChildrenChanged) {
System.out.println("zookeeper有子節點變化" + event.getPath());
}
}else{
System.out.println("zookeeper 未判斷異常 path "+path+" event"+event);
}
}
}