
com.app.common.cluster.ZkCluster Maven / Gradle / Ivy
package com.app.common.cluster;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import org.I0Itec.zkclient.IZkChildListener;
import org.I0Itec.zkclient.IZkDataListener;
import org.apache.commons.lang3.StringUtils;
import org.apache.zookeeper.CreateMode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.app.common.encrypt.RSA;
import com.app.common.utils.StringUtil;
import com.app.common.zk.ZookeeperClient;
import com.gw.common.utils.Consts;
/**
* 基于zookeeper实现集群模式
*
* @author deshuai.kong
*
*/
public class ZkCluster extends AbstractCluster {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private String root = "/MDTService";
public static ZookeeperClient zk = null;
private String zkHosts;
private ConcurrentHashMap chm = new ConcurrentHashMap<>();
@Override
public String getClusterName() {
return "ZK";
}
@Override
public synchronized void startServer(ServerInfo serverInfo) throws Exception {
if (serverInfo.isRegisterEnable()) {
createZkClient(serverInfo);
}
createServerNode(serverInfo, true);
}
private synchronized void createZkClient(ServerInfo serverInfo) {
logger.info("createZkClient:{},{}", serverInfo, serverInfo.atts);
if (zk == null) {
HashMap hm = serverInfo.atts;
if (hm != null && hm.size() > 0) {
zkHosts = hm.get("Cluster.Zookeeper.Hosts") + "";
String zkUserName = null;
String zkPassword = null;
if (hm.containsKey("Cluster.Zookeeper.UserName")) {
zkUserName = hm.get("Cluster.Zookeeper.UserName") + "";
}
if (hm.containsKey("Cluster.Zookeeper.Password")) {
zkPassword = hm.get("Cluster.Zookeeper.Password") + "";
}
if (hm.containsKey("Cluster.Zookeeper.PrivateKey")) {
String privateKey = hm.get("Cluster.Zookeeper.PrivateKey") + "";
if(StringUtil.isNotBlank(privateKey)) {
try {
zkPassword=RSA.decrypt(zkPassword, privateKey);
} catch (Exception e) {
logger.error("decrypt:{},{},{}",zkPassword,privateKey,e);
}
}
}
zk = new ZookeeperClient(zkHosts, zkUserName, zkPassword);
}
}
}
private IZkChildListener zkChildListener = new IZkChildListener() {
@Override
public void handleChildChange(String parentPath, List currentChilds) throws Exception {
try {
int index = parentPath.lastIndexOf("/");
String sName = parentPath.substring(index + 1, parentPath.length());
logger.info("handleChildChange:{},{}", parentPath, sName);
// client
List lt = getServerInfo(sName, parentPath, currentChilds);
for (ServerInfo serverInfo : lt) {
logger.info("getServerInfo1:{}", serverInfo);
}
IClusterClientListener cc = chmClusterClient.get(sName);
if (cc != null) {
logger.info("onClustChange:{}", sName);
cc.onClustChange(lt);
}
// server
ServerInfo serverInfo = chm.get(sName);
if (serverInfo != null) {
if ("1".equals(serverInfo.getStat())) {
boolean isStop = true;
if(lt.size()==0) {
boolean flag=createServerNode(serverInfo, false);
if(flag) {
return;
}
}
for (String name : currentChilds) {
String sTempPathNode = parentPath + "/" + name;
String content = zk.readData(sTempPathNode) + "";
ServerInfo si = getServerInfoByNodeInfo(content);
si.setSeqName(name);
si.setName(sName);
if (si != null) {
if (si.getHost().equals(serverInfo.getHost()) && si.getPort() == serverInfo.getPort()
&& "1".equals(serverInfo.getStat())) {
isStop = false;
}
}
}
if (isStop) {
serverInfo.setStat("0");
serverInfo.setSeqName("");
stop(serverInfo);
}
}
createServerNode(serverInfo, false);
}
} catch (Exception e) {
logger.error("handleChildChange", e);
}
}
};
private List getServerInfo(String serverName, String parentPath, List currentChilds) {
List lt = new ArrayList();
for (String name : currentChilds) {
String sTempPathNode = parentPath + "/" + name;
String content = zk.readData(sTempPathNode) + "";
logger.info("currentChilds:{},{},{}", sTempPathNode, name, content);
ServerInfo si = getServerInfoByNodeInfo(content);
if (si != null && "1".equals(si.getStat())) {
si.setSeqName(name);
si.setName(serverName);
lt.add(si);
}
}
return lt;
}
IZkDataListener zkDataListener = new IZkDataListener() {
@Override
public void handleDataDeleted(String dataPath) throws Exception {
logger.info("handleDataDeleted:" + dataPath);
List lt = new ArrayList();
int index = dataPath.lastIndexOf("/");
String sName = dataPath.substring(index + 1, dataPath.length());
IClusterClientListener cc = chmClusterClient.get(sName);
if (cc != null) {
logger.info("onClustChange:{}", sName);
cc.onClustChange(lt);
}
}
@Override
public void handleDataChange(String dataPath, Object data) throws Exception {
logger.info("handleDataChange:" + dataPath + "," + data);
List lt = new ArrayList();
int index = dataPath.lastIndexOf("/");
String sName = dataPath.substring(index + 1, dataPath.length());
String content = data + "";
ServerInfo si = getServerInfoByNodeInfo(content);
if (si != null && "1".equals(si.getStat())) {
si.setSeqName(sName);
si.setName(sName);
lt.add(si);
}
for (ServerInfo serverInfo : lt) {
logger.info("getServerInfo:{}", serverInfo);
}
IClusterClientListener cc = chmClusterClient.get(sName);
if (cc != null) {
logger.info("onClustChange:{}", sName);
cc.onClustChange(lt);
}
}
};
private boolean createServerNode(ServerInfo serverInfo, boolean isFrist) {
boolean flag = false;
if (!serverInfo.isRegisterEnable()) {
start(serverInfo);// 拉起服务
return true;
}
if (!zk.exists(root)) {
zk.create(root, "", CreateMode.PERSISTENT);// 创建持久根节点
}
String sPathNode = root + "/" + serverInfo.getName();
if (!zk.exists(sPathNode)) {
String data = ServerInfo.TYPE[serverInfo.getType()];
zk.create(sPathNode, data, CreateMode.PERSISTENT);// 创建持久服务节点
}
if (isFrist) {
zk.subscribeChildChanges(sPathNode, zkChildListener);
chm.put(serverInfo.getName(), serverInfo);
}
boolean isCreateServerNode = true;
if (!StringUtils.isEmpty(serverInfo.getSeqName())) {
String sTempPathNode = sPathNode + "/" + serverInfo.getSeqName();
if (zk.exists(sTempPathNode)) {
isCreateServerNode = false;
} else {
serverInfo.setStat("0");
serverInfo.setSeqName("");
}
}
if (isCreateServerNode) {
String sTempPathNode = sPathNode + "/" + serverInfo.getName();
try {
if (!zk.exists(sTempPathNode)) {
CreateMode cm = CreateMode.EPHEMERAL_SEQUENTIAL;
if (serverInfo.getType() == (ServerInfo.TYPE_STANDBY)) {// 主备机模式
cm = CreateMode.EPHEMERAL;
}
if (serverInfo.getType() == (ServerInfo.TYPE_STANDBY)) {
String data = String.format("Host:%s,Port:%s,Stat:%s", serverInfo.getHost(),
serverInfo.getPort(), "0");
logger.info("zk.create:{}:{}", sTempPathNode,data);
String seqName = zk.create(sTempPathNode, data, cm);// 创建临时服务节点
seqName = seqName.replace(sPathNode + "/", "");
serverInfo.setSeqName(seqName);
serverInfo.setStat("1");
start(serverInfo);// 拉起服务
sTempPathNode = sPathNode + "/" + serverInfo.getSeqName();
data = String.format("Host:%s,Port:%s,Stat:%s", serverInfo.getHost(), serverInfo.getPort(),
"1");
zk.writeData(sTempPathNode, data);// 激活服务
logger.info("zk.writeData:{}:{}", sTempPathNode,data);
} else {
if (isFrist) {
start(serverInfo);// 拉起服务
String data = String.format("Host:%s,Port:%s,Stat:%s", serverInfo.getHost(),
serverInfo.getPort(), "1");
logger.info("zk.create:{}:{}", sTempPathNode,data);
String seqName = zk.create(sTempPathNode, data, cm);// 创建临时服务节点
seqName = seqName.replace(sPathNode + "/", "");
serverInfo.setSeqName(seqName);
serverInfo.setStat("1");
}
}
flag = true;
}
} catch (Exception e) {
logger.error("", e);
}
}
return flag;
}
private ServerInfo getServerInfoByNodeInfo(String content) {
ServerInfo si = null;
String[] strs = content.split(",");
if (strs.length > 1) {
si = new ServerInfo();
}
for (String str : strs) {
String[] strs2 = str.split(":");
if (strs2.length == 2) {
if ("Stat".equals(strs2[0])) {
si.setStat(strs2[1]);
}
if ("Host".equals(strs2[0])) {
si.setHost(strs2[1]);
}
if ("Port".equals(strs2[0])) {
si.setPort(Integer.parseInt(strs2[1]));
}
}
}
return si;
}
// client
private ConcurrentHashMap chmClusterClient = new ConcurrentHashMap<>();
private ConcurrentHashMap chmZkChild = new ConcurrentHashMap<>();
@Override
public void startClient(ServerInfo serverInfo, IClusterClientListener clusterListener) {
createZkClient(serverInfo);
chmClusterClient.put(serverInfo.getName(), clusterListener);
listenerServerNode(serverInfo);
}
private void listenerServerNode(ServerInfo serverInfo) {
logger.info("{} listenerServerNode ", serverInfo.getName());
if (zk == null) {
logger.info("{} zk is null ", serverInfo.getName());
return;
}
if (!zk.exists(root)) {
zk.create(root, "", CreateMode.PERSISTENT);// 创建持久根节点
}
String sPathNode = root + "/" + serverInfo.getName();
if (!zk.exists(sPathNode)) {
String data = ServerInfo.TYPE[serverInfo.getType()];
zk.create(sPathNode, data, CreateMode.PERSISTENT);// 创建持久服务节点
}
if (!chmZkChild.containsKey(sPathNode)) {
if (serverInfo.getType() == (ServerInfo.TYPE_STANDBY)) {
zk.subscribeDataChanges(sPathNode + "/" + serverInfo.getName(), zkDataListener);
} else {
zk.subscribeChildChanges(sPathNode, zkChildListener);
}
}
}
public List getServerInfo(ServerInfo serverInfo) {
List slt = new ArrayList();
if (zk != null) {
createZkClient(serverInfo);
String sPathNode = root + "/" + serverInfo.getName();
List lt = zk.getChildren(sPathNode);
List siLt = getServerInfo(serverInfo.getName(), sPathNode, lt);
for (ServerInfo si : siLt) {
if ("1".equals(si.getStat()) && StringUtil.isNotBlank(si.getHost()) && !Consts.ServerInfo.equals(si.toString())) {
slt.add(si);
}
logger.info("getServerInfo:{}", si);
}
}
return slt;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy