package com.taobao.top.analysis; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jboss.netty.handler.codec.serialization.ClassResolvers; import org.jboss.netty.handler.codec.serialization.ObjectDecoder; import org.jboss.netty.handler.codec.serialization.ObjectEncoder; import org.jboss.netty.logging.InternalLoggerFactory; import org.jboss.netty.logging.Log4JLoggerFactory; import com.taobao.top.analysis.config.AbstractConfig; import com.taobao.top.analysis.config.IConfig; import com.taobao.top.analysis.config.MasterConfig; import com.taobao.top.analysis.config.SlaveConfig; import com.taobao.top.analysis.exception.AnalysisException; import com.taobao.top.analysis.node.IJobBuilder; import com.taobao.top.analysis.node.IJobExporter; import com.taobao.top.analysis.node.IJobManager; import com.taobao.top.analysis.node.IJobResultMerger; import com.taobao.top.analysis.node.INode; import com.taobao.top.analysis.node.component.FileJobExporter; import com.taobao.top.analysis.node.component.JobManager; import com.taobao.top.analysis.node.component.JobResultMerger; import com.taobao.top.analysis.node.component.MasterMonitor; import com.taobao.top.analysis.node.component.MasterNode; import com.taobao.top.analysis.node.component.MixJobBuilder; import com.taobao.top.analysis.node.component.SlaveMonitor; import com.taobao.top.analysis.node.component.SlaveNode; import com.taobao.top.analysis.node.connect.IMasterConnector; import com.taobao.top.analysis.node.connect.ISlaveConnector; import com.taobao.top.analysis.node.connect.SocketMasterConnector; import com.taobao.top.analysis.node.connect.SocketSlaveConnector; import com.taobao.top.analysis.node.event.MasterEventCode; import com.taobao.top.analysis.node.event.MasterNodeEvent; import com.taobao.top.analysis.node.io.FileInputAdaptor; import com.taobao.top.analysis.node.io.FileOutputAdaptor; import com.taobao.top.analysis.node.io.HdfsInputAdaptor; import com.taobao.top.analysis.node.io.HttpInputAdaptor; import com.taobao.top.analysis.node.io.HubInputAdaptor; import com.taobao.top.analysis.node.io.IInputAdaptor; import com.taobao.top.analysis.node.io.IOutputAdaptor; import com.taobao.top.analysis.node.monitor.IMonitor; import com.taobao.top.analysis.statistics.IStatisticsEngine; import com.taobao.top.analysis.statistics.StatisticsEngine; import com.taobao.top.analysis.util.AnalyzerUtil; /** * TopAnalysisNode.java * @author yunzhan.jtq * * @since 2012-2-3 上午10:40:15 */ public class TopAnalysisNode implements Runnable { private static final Log log = LogFactory.getLog(TopAnalysisNode.class); /** * 如果是master,则初始化为MasterNode; * 如果是slave,则初始化为SlaveNode */ private INode<?, ?> node = null; /** * 如果是master,则初始化为JobManager */ private IJobManager jobManager = null; /** * 如果是master,则初始化为MixJobBuilder */ private IJobBuilder jobBuilder = null; /** * 服务端和客户端交互通道 * http访问 */ // private MemTunnel tunnel = null; /** * 服务端通信组件 */ private IMasterConnector masterConnector = null; /** * 客户端通信组件 */ private ISlaveConnector slaveConnector = null; /** * 监控组件 */ private IMonitor<?> monitor = null; /** * 任务合并组件 */ private IJobResultMerger jobResultMerger = null; /** * 报表输出组件 * 如果是master,则初始化为FileJobExporter */ private IJobExporter jobExporter = null; /** * 如果是master,则为masterConfig; * 如果是slave,则为slaveConfig */ private IConfig nodeConfig = null; /** * 计算引擎 */ private IStatisticsEngine statisticsEngine = null; /** * http输入适配器 */ private IInputAdaptor httpInputAdaptor = null; /** * hdfs输入适配器 */ private IInputAdaptor hdfsInputAdaptor = null; /** * file输入适配器 */ private IInputAdaptor fileInputAdaptor = null; /** * hub输入适配器 */ private IInputAdaptor hubInputAdaptor = null; /** * file输出适配器 */ private IOutputAdaptor fileOutputAdaptor = null; /** * 初始化标志 */ private AtomicBoolean init = new AtomicBoolean(false); /** * 同步http服务 */ private HttpAgentNode httpAgentNode = null; /** * 扫描线程 * 目前只用于扫描配置文件变更 */ private java.util.concurrent.ScheduledExecutorService scanService = java.util.concurrent.Executors .newScheduledThreadPool(3); /** * @param args */ public static void main(String[] args) { if (args == null || args.length < 2 || args[0] == null || args[0].equals("") || args[1] == null || args[1].equals("")) { System.out.println("usage : java -jar TopAnalyzer.jar propFile master"); log.error("usage : java -jar TopAnalyzer.jar propFile master"); return; } Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException(Thread t, Throwable e) { if (!(e instanceof ThreadDeath)) { System.err.print("Exception in thread \"" + t.getName() + "\" "); e.printStackTrace(System.err); } } }); System.out.println("BuildDate:"+AnalyzerUtil.getManifestBuildDate()); final TopAnalysisNode topAnalyzerNode = new TopAnalysisNode(); try { topAnalyzerNode.init(args[0], "master".equalsIgnoreCase(args[1])); } catch(Throwable e) { log.error(e, e); } topAnalyzerNode.start(); // topAnalyzerNode.run(); } /** * 初始化各个类 * 很多配置目前是硬编码,后续将根据配置的不同选择不同的配置 */ public void init(String propertyFile, boolean isMaster) { jobResultMerger = new JobResultMerger(); jobExporter = new FileJobExporter(); InternalLoggerFactory.setDefaultFactory(new Log4JLoggerFactory()); if(isMaster) { //init Master buildMaster(); } else { //init slave buildSlave(); } nodeConfig.load(propertyFile); java.lang.Runtime.getRuntime().addShutdownHook(new Thread(new Runnable(){ @Override public void run() { releaseResource(); } })); this.init.compareAndSet(false, true); } /** * 开启节点 * 并开启配置扫描线程 */ public void start() { if(!this.init.get()) { log.error("node init failed, please check the config"); throw new java.lang.RuntimeException("node init failed, please check the config"); } node.startNode(); httpAgentNode.start(); scanService.scheduleAtFixedRate(this, 5, ((AbstractConfig)nodeConfig).getScanFileTime(), TimeUnit.SECONDS); } /* (non-Javadoc) * @see java.lang.Runnable#run() */ @Override public void run() { try { this.checkConfigModified(); } catch (Throwable e) { log.error(e); } } /** * 初始化master */ private void buildMaster() { node = new MasterNode(); nodeConfig = new MasterConfig(); jobManager = new JobManager(); jobBuilder = new MixJobBuilder(); masterConnector = new SocketMasterConnector(); monitor = new MasterMonitor(); httpAgentNode = new HttpAgentNode(); ((MasterNode)node).setConfig((MasterConfig)nodeConfig); ObjectDecoder objDecoder = new ObjectDecoder(Integer.MAX_VALUE, ClassResolvers.weakCachingConcurrentResolver(this.getClass().getClassLoader())); ((SocketMasterConnector)masterConnector).setDownstreamHandler(new ObjectEncoder()); ((SocketMasterConnector)masterConnector).setUpstreamHandler(objDecoder); jobManager.setJobBuilder(jobBuilder); jobManager.setJobExporter(jobExporter); jobManager.setJobResultMerger(jobResultMerger); ((MasterNode)node).setJobManager(jobManager); ((MasterNode)node).setMasterConnector(masterConnector); ((MasterNode)node).setMonitor((MasterMonitor)monitor); httpAgentNode.setJobManager(jobManager); httpAgentNode.setName("top-analysis-http-agent"); } /** * 初始化slave */ private void buildSlave() { node = new SlaveNode(); nodeConfig = new SlaveConfig(); slaveConnector = new SocketSlaveConnector(); monitor = new SlaveMonitor(); statisticsEngine = new StatisticsEngine(); httpInputAdaptor = new HttpInputAdaptor(); hdfsInputAdaptor = new HdfsInputAdaptor(); fileInputAdaptor = new FileInputAdaptor(); hubInputAdaptor = new HubInputAdaptor(); fileOutputAdaptor = new FileOutputAdaptor(); try { jobExporter.init(); } catch (AnalysisException e) { log.error("init jobExporter failed", e); } ((FileOutputAdaptor)fileOutputAdaptor).setJobExporter(jobExporter); ((SocketSlaveConnector)slaveConnector).setDownstreamHandler(new ObjectEncoder(8192 * 4)); ((SocketSlaveConnector)slaveConnector).setUpstreamHandler(new ObjectDecoder(Integer.MAX_VALUE, ClassResolvers.weakCachingConcurrentResolver(this.getClass().getClassLoader()))); ((SlaveNode)node).setConfig((SlaveConfig) nodeConfig); ((SlaveNode)node).setJobResultMerger(jobResultMerger); ((SlaveNode)node).setSlaveConnector(slaveConnector); ((SlaveNode)node).setStatisticsEngine(statisticsEngine); ((SlaveNode)node).setMonitor((SlaveMonitor)monitor); statisticsEngine.addInputAdaptor(httpInputAdaptor); statisticsEngine.addInputAdaptor(hdfsInputAdaptor); statisticsEngine.addInputAdaptor(fileInputAdaptor); statisticsEngine.addInputAdaptor(hubInputAdaptor); statisticsEngine.addOutputAdaptor(fileOutputAdaptor); } private void checkConfigModified() { if(!this.init.get()) return; if(nodeConfig.isNeedReload()) { nodeConfig.reload(); log.error("node'config is modified, reloading executed, please have a check"); } if(!(nodeConfig instanceof MasterConfig) || jobBuilder == null) return; if (jobBuilder.isModified()) { MasterNodeEvent e = new MasterNodeEvent(); e.setEventCode(MasterEventCode.RELOAD_JOBS); ((MasterNode)node).addEvent(e); log.error("job'config is modified, reloading executed, please have a check"); String content = null; try { content = "Host:" + InetAddress.getLocalHost().getHostAddress() + ",config file was modified!!!"; } catch (UnknownHostException e1) { log.error(e1); } AbstractConfig tmpConfig = (AbstractConfig)nodeConfig; if(tmpConfig.isEnableAlert()) AnalyzerUtil.sendOutAlert(java.util.Calendar.getInstance(), tmpConfig.getAlertUrl(), tmpConfig.getAlertFrom(), tmpConfig.getAlertModel(), tmpConfig.getAlertWangWang(), content); } } public void releaseResource() { node.releaseResource(); scanService.shutdown(); } public void stopNode() { node.stopNode(); } }