![JAR search and dependency download from the Maven repository](/logo.png)
com.github.ltsopensource.core.cluster.AbstractJobNode Maven / Gradle / Ivy
package com.github.ltsopensource.core.cluster;
import com.github.ltsopensource.cmd.HttpCmdServer;
import com.github.ltsopensource.core.AppContext;
import com.github.ltsopensource.core.cmd.JVMInfoGetHttpCmd;
import com.github.ltsopensource.core.cmd.StatusCheckHttpCmd;
import com.github.ltsopensource.core.commons.utils.CollectionUtils;
import com.github.ltsopensource.core.commons.utils.GenericsUtils;
import com.github.ltsopensource.core.commons.utils.NetUtils;
import com.github.ltsopensource.core.commons.utils.StringUtils;
import com.github.ltsopensource.core.compiler.AbstractCompiler;
import com.github.ltsopensource.core.constant.EcTopic;
import com.github.ltsopensource.core.constant.ExtConfig;
import com.github.ltsopensource.core.factory.JobNodeConfigFactory;
import com.github.ltsopensource.core.factory.NodeFactory;
import com.github.ltsopensource.core.json.JSONFactory;
import com.github.ltsopensource.core.listener.MasterChangeListener;
import com.github.ltsopensource.core.listener.MasterElectionListener;
import com.github.ltsopensource.core.listener.NodeChangeListener;
import com.github.ltsopensource.core.listener.SelfChangeListener;
import com.github.ltsopensource.core.logger.Logger;
import com.github.ltsopensource.core.logger.LoggerFactory;
import com.github.ltsopensource.core.protocol.command.CommandBodyWrapper;
import com.github.ltsopensource.core.registry.*;
import com.github.ltsopensource.core.spi.ServiceLoader;
import com.github.ltsopensource.core.support.AliveKeeping;
import com.github.ltsopensource.core.support.ConfigValidator;
import com.github.ltsopensource.ec.EventCenter;
import com.github.ltsopensource.ec.EventInfo;
import com.github.ltsopensource.remoting.serialize.AdaptiveSerializable;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* @author Robert HG ([email protected]) on 8/15/14.
* 抽象节点
*/
public abstract class AbstractJobNode implements JobNode {
protected static final Logger LOGGER = LoggerFactory.getLogger(JobNode.class);
protected Registry registry;
protected T node;
protected Config config;
protected Context appContext;
private List nodeChangeListeners;
private List masterChangeListeners;
protected AtomicBoolean started = new AtomicBoolean(false);
public AbstractJobNode() {
appContext = getAppContext();
node = NodeFactory.create(getNodeClass());
config = JobNodeConfigFactory.getDefaultConfig();
config.setNodeType(node.getNodeType());
appContext.setConfig(config);
nodeChangeListeners = new ArrayList();
masterChangeListeners = new ArrayList();
}
final public void start() {
try {
if (started.compareAndSet(false, true)) {
configValidate();
// 初始化配置
initConfig();
// 初始化HttpCmdServer
initHttpCmdServer();
beforeRemotingStart();
remotingStart();
afterRemotingStart();
initRegistry();
registry.register(node);
AliveKeeping.start();
LOGGER.info("========== Start success, nodeType={}, identity={}", config.getNodeType(), config.getIdentity());
}
} catch (Throwable e) {
if (e.getMessage().contains("Address already in use")) {
LOGGER.error("========== Start failed at listen port {}, nodeType={}, identity={}", config.getListenPort(), config.getNodeType(), config.getIdentity(), e);
} else {
LOGGER.error("========== Start failed, nodeType={}, identity={}", config.getNodeType(), config.getIdentity(), e);
}
}
}
private void initHttpCmdServer() {
// 命令中心
int port = appContext.getConfig().getParameter(ExtConfig.HTTP_CMD_PORT, 8719);
appContext.setHttpCmdServer(HttpCmdServer.Factory.getHttpCmdServer(config.getIp(), port));
// 先启动,中间看端口是否被占用
appContext.getHttpCmdServer().start();
// 设置command端口,会暴露到注册中心上
node.setHttpCmdPort(appContext.getHttpCmdServer().getPort());
appContext.getHttpCmdServer().registerCommands(
new StatusCheckHttpCmd(appContext.getConfig()),
new JVMInfoGetHttpCmd(appContext.getConfig())); // 状态检查
}
final public void stop() {
try {
if (started.compareAndSet(true, false)) {
if (registry != null) {
registry.unregister(node);
}
beforeRemotingStop();
remotingStop();
afterRemotingStop();
appContext.getEventCenter().publishSync(new EventInfo(EcTopic.NODE_SHUT_DOWN));
AliveKeeping.stop();
LOGGER.info("========== Stop success, nodeType={}, identity={}", config.getNodeType(), config.getIdentity());
}
} catch (Throwable e) {
LOGGER.error("========== Stop failed, nodeType={}, identity={}", config.getNodeType(), config.getIdentity(), e);
}
}
@Override
public void destroy() {
try {
registry.destroy();
LOGGER.info("Destroy success, nodeType={}, identity={}", config.getNodeType(), config.getIdentity());
} catch (Throwable e) {
LOGGER.error("Destroy failed, nodeType={}, identity={}", config.getNodeType(), config.getIdentity(), e);
}
}
protected void configValidate() {
ConfigValidator.validateNodeGroup(config.getNodeGroup());
ConfigValidator.validateClusterName(config.getClusterName());
ConfigValidator.validateIdentity(config.getIdentity());
}
protected void initConfig() {
String compiler = config.getParameter(ExtConfig.COMPILER);
if (StringUtils.isNotEmpty(compiler)) {
AbstractCompiler.setCompiler(compiler);
}
if (StringUtils.isEmpty(config.getIp())) {
config.setIp(NetUtils.getLocalHost());
}
if (StringUtils.isEmpty(config.getIdentity())) {
JobNodeConfigFactory.buildIdentity(config);
}
NodeFactory.build(node, config);
LOGGER.info("Current Node config :{}", config);
appContext.setEventCenter(ServiceLoader.load(EventCenter.class, config));
appContext.setCommandBodyWrapper(new CommandBodyWrapper(config));
appContext.setMasterElector(new MasterElector(appContext));
appContext.getMasterElector().addMasterChangeListener(masterChangeListeners);
appContext.setRegistryStatMonitor(new RegistryStatMonitor(appContext));
// 订阅的node管理
SubscribedNodeManager subscribedNodeManager = new SubscribedNodeManager(appContext);
appContext.setSubscribedNodeManager(subscribedNodeManager);
nodeChangeListeners.add(subscribedNodeManager);
// 用于master选举的监听器
nodeChangeListeners.add(new MasterElectionListener(appContext));
// 监听自己节点变化(如,当前节点被禁用了)
nodeChangeListeners.add(new SelfChangeListener(appContext));
setSpiConfig();
}
private void setSpiConfig() {
// 设置默认序列化方式
String defaultSerializable = config.getParameter(ExtConfig.REMOTING_SERIALIZABLE_DFT);
if (StringUtils.isNotEmpty(defaultSerializable)) {
AdaptiveSerializable.setDefaultSerializable(defaultSerializable);
}
// 设置json
String ltsJson = config.getParameter(ExtConfig.LTS_JSON);
if (StringUtils.isNotEmpty(ltsJson)) {
JSONFactory.setJSONAdapter(ltsJson);
}
// 设置logger
String logger = config.getParameter(ExtConfig.LTS_LOGGER);
if (StringUtils.isNotEmpty(logger)) {
LoggerFactory.setLoggerAdapter(logger);
}
}
private void initRegistry() {
registry = RegistryFactory.getRegistry(appContext);
if (registry instanceof AbstractRegistry) {
((AbstractRegistry) registry).setNode(node);
}
registry.subscribe(node, new NotifyListener() {
private final Logger NOTIFY_LOGGER = LoggerFactory.getLogger(NotifyListener.class);
@Override
public void notify(NotifyEvent event, List nodes) {
if (CollectionUtils.isEmpty(nodes)) {
return;
}
switch (event) {
case ADD:
for (NodeChangeListener listener : nodeChangeListeners) {
try {
listener.addNodes(nodes);
} catch (Throwable t) {
NOTIFY_LOGGER.error("{} add nodes failed , cause: {}", listener.getClass().getName(), t.getMessage(), t);
}
}
break;
case REMOVE:
for (NodeChangeListener listener : nodeChangeListeners) {
try {
listener.removeNodes(nodes);
} catch (Throwable t) {
NOTIFY_LOGGER.error("{} remove nodes failed , cause: {}", listener.getClass().getName(), t.getMessage(), t);
}
}
break;
}
}
});
}
protected abstract void remotingStart();
protected abstract void remotingStop();
protected abstract void beforeRemotingStart();
protected abstract void afterRemotingStart();
protected abstract void beforeRemotingStop();
protected abstract void afterRemotingStop();
@SuppressWarnings("unchecked")
private Context getAppContext() {
try {
return ((Class)
GenericsUtils.getSuperClassGenericType(this.getClass(), 1))
.newInstance();
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
@SuppressWarnings("unchecked")
private Class getNodeClass() {
return (Class)
GenericsUtils.getSuperClassGenericType(this.getClass(), 0);
}
/**
* 设置zookeeper注册中心地址
*/
public void setRegistryAddress(String registryAddress) {
config.setRegistryAddress(registryAddress);
}
/**
* 设置远程调用超时时间
*/
public void setInvokeTimeoutMillis(int invokeTimeoutMillis) {
config.setInvokeTimeoutMillis(invokeTimeoutMillis);
}
/**
* 设置集群名字
*/
public void setClusterName(String clusterName) {
config.setClusterName(clusterName);
}
/**
* 节点标识(必须要保证这个标识是唯一的才能设置,请谨慎设置)
* 这个是非必须设置的,建议使用系统默认生成
*/
public void setIdentity(String identity) {
config.setIdentity(identity);
}
/**
* 添加节点监听器
*/
public void addNodeChangeListener(NodeChangeListener notifyListener) {
if (notifyListener != null) {
nodeChangeListeners.add(notifyListener);
}
}
/**
* 显示设置绑定ip
*/
public void setBindIp(String bindIp) {
if (StringUtils.isEmpty(bindIp)
|| !NetUtils.isValidHost(bindIp)
) {
throw new IllegalArgumentException("Invalided bind ip:" + bindIp);
}
config.setIp(bindIp);
}
/**
* 添加 master 节点变化监听器
*/
public void addMasterChangeListener(MasterChangeListener masterChangeListener) {
if (masterChangeListener != null) {
masterChangeListeners.add(masterChangeListener);
}
}
public void setDataPath(String path) {
if (StringUtils.isNotEmpty(path)) {
config.setDataPath(path);
}
}
/**
* 设置额外的配置参数
*/
public void addConfig(String key, String value) {
config.setParameter(key, value);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy