/** * */ package com.taobao.top.analysis.node.component; import java.util.List; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.zookeeper.ZooKeeper; import com.taobao.top.analysis.config.MasterConfig; import com.taobao.top.analysis.exception.AnalysisException; import com.taobao.top.analysis.node.IJobManager; import com.taobao.top.analysis.node.connect.IMasterConnector; import com.taobao.top.analysis.node.event.GetTaskRequestEvent; import com.taobao.top.analysis.node.event.GetTaskResponseEvent; import com.taobao.top.analysis.node.event.JobManageEvent; import com.taobao.top.analysis.node.event.MasterNodeEvent; import com.taobao.top.analysis.node.event.SendMonitorInfoEvent; import com.taobao.top.analysis.node.event.SendMonitorInfoResponseEvent; import com.taobao.top.analysis.node.event.SendResultsRequestEvent; import com.taobao.top.analysis.node.event.SendResultsResponseEvent; import com.taobao.top.analysis.node.job.JobTask; import com.taobao.top.analysis.node.monitor.MasterMonitorInfo; import com.taobao.top.analysis.node.monitor.NHttpServer; import com.taobao.top.analysis.util.AnalyzerZKWatcher; import com.taobao.top.analysis.util.ZKUtil; /** * 分布式集群 Master Node (可以是虚拟机内部的) * 使用方式参考MasterSlaveIntegrationTest 类 * @author fangweng * @Email fangweng@taobao.com * 2011-11-28 * */ public class MasterNode extends AbstractNode<MasterNodeEvent,MasterConfig> { private static final Log logger = LogFactory.getLog(MasterNode.class); /** * 任务管理组件 */ private IJobManager jobManager; /** * 用于与Slave通信的组件 */ private IMasterConnector masterConnector; /** * Master监控组件 */ private MasterMonitor monitor; /** * HTTP服务组件 */ private NHttpServer httpServer; public IJobManager getJobManager() { return jobManager; } public void setJobManager(IJobManager jobManager) { this.jobManager = jobManager; } public IMasterConnector getMasterConnector() { return masterConnector; } public void setMasterConnector(IMasterConnector masterConnector) { this.masterConnector = masterConnector; } public MasterMonitor getMonitor() { return monitor; } public void setMonitor(MasterMonitor monitor) { this.monitor = monitor; } @Override public void init() throws AnalysisException { httpServer = new NHttpServer(); httpServer.setConfig(config); jobManager.setMasterNode(this); jobManager.setConfig(config); masterConnector.setMasterNode(this); masterConnector.setConfig(config); monitor.setConfig(config); jobManager.init(); masterConnector.init(); monitor.init(); httpServer.setMonitor(monitor); // httpServer.setJobManager(jobManager); httpServer.init(); //增加一块对于zookeeper的支持 if (StringUtils.isNotEmpty(config.getZkServer())) { try { AnalyzerZKWatcher<MasterConfig> analyzerZKWatcher = new AnalyzerZKWatcher<MasterConfig>(config); zk = new ZooKeeper(config.getZkServer(),3000,analyzerZKWatcher); analyzerZKWatcher.setZk(zk); //每次启动时都先检查是否有根目录 ZKUtil.createGroupNodesIfNotExist(zk,config.getGroupId()); ZKUtil.updateOrCreateNode(zk,ZKUtil.getGroupMasterZKPath(config.getGroupId()) + "/" + config.getMasterName(),config.marshal().getBytes("UTF-8")); } catch(Exception ex) { logger.error("config to zk error!",ex); } } logger.warn("Master init ok"); if (logger.isInfoEnabled()) logger.info("Master init complete."); } @Override public void releaseResource() { if (jobManager != null) jobManager.releaseResource(); if(monitor != null) { monitor.releaseResource(); } if (masterConnector != null) masterConnector.releaseResource(); //增加一块对于zookeeper的支持 if (StringUtils.isNotEmpty(config.getZkServer()) && zk != null) { try { ZKUtil.deleteNode(zk,ZKUtil.getGroupMasterZKPath(config.getGroupId()) + "/" + config.getMasterName()); } catch(Exception ex) { logger.error("delete zk node error!",ex); } } if (logger.isInfoEnabled()) logger.info("Master releaseResource complete."); } @Override public void process() throws AnalysisException { try { jobManager.checkJobStatus(); } catch (Throwable e) { logger.error(e); } } /** * 响应请求任务的逻辑 * @param sequence * @param jobTasks */ public void echoGetJobTasks(String sequence,List<JobTask> jobTasks,Object channel) { GetTaskResponseEvent event = new GetTaskResponseEvent(sequence); event.setJobTasks(jobTasks); event.setChannel(channel); masterConnector.echoGetJobTasks(event); } /** * 响应Slave提交任务结果的请求 * @param 返回结果 */ public void echoSendJobTaskResults(String sequence,String response,Object channel) { SendResultsResponseEvent event = new SendResultsResponseEvent(sequence); event.setResponse(response); event.setChannel(channel); masterConnector.echoSendJobTaskResults(event); } public void echoSendMonitorInfo(String sequence, MasterMonitorInfo info, Object channel) { SendMonitorInfoResponseEvent event = new SendMonitorInfoResponseEvent(sequence); event.setMasterMonitorInfo(info); event.setChannel(channel); masterConnector.echoSendMonitorInfo(event); } @Override public void processEvent(MasterNodeEvent event) throws AnalysisException { switch (event.getEventCode()) { case GET_TASK: jobManager.getUnDoJobTasks((GetTaskRequestEvent)event); if (logger.isInfoEnabled()) logger.info("Master process GET_TASK Event"); break; case SEND_RESULT: jobManager.addTaskResultToQueue((SendResultsRequestEvent)event); monitor.report(((SendResultsRequestEvent)event).getJobTaskResult().getJobName(), ((SendResultsRequestEvent)event).getJobTaskResult().getTaskExecuteInfos().values()); if (logger.isInfoEnabled()) logger.info("Master process SEND_RESULT Event"); break; case SEND_MONITOR_INFO: MasterMonitorInfo info = monitor.report(((SendMonitorInfoEvent)event).getSlaveMonitorInfo()); this.echoSendMonitorInfo(event.getSequence(), info, event.getChannel()); break; case RELOAD_JOBS: jobManager.getJobBuilder().setNeedRebuild(true); if (logger.isInfoEnabled()) logger.info("Master process RELOAD_JOBS Event"); break; case EXPORT_DATA: jobManager.exportJobData(((JobManageEvent)event).getJobName()); if (logger.isInfoEnabled()) logger.info("Master process EXPORT_DATA Event"); break; case CLEAR_DATA: jobManager.clearJobData(((JobManageEvent)event).getJobName()); if (logger.isInfoEnabled()) logger.info("Master process CLEAR_DATA Event"); break; case LOAD_DATA: jobManager.loadJobData(((JobManageEvent)event).getJobName()); if (logger.isInfoEnabled()) logger.info("Master process LOAD_DATA Event"); break; case LOAD_DATA_TO_TMP: jobManager.loadJobDataToTmp(((JobManageEvent)event).getJobName()); if (logger.isInfoEnabled()) logger.info("Master process LOAD_DATA_TO_TMP Event"); break; case LOAD_BACKUP_DATA: jobManager.loadJobBackupData(((JobManageEvent)event).getJobName() ,(String)((JobManageEvent)event).getAttachment()); if (logger.isInfoEnabled()) logger.info("Master process LOAD_BACKUP_DATA Event"); break; case SUSPEND: this.suspendNode(); break; case AWAKE: this.awaitNode(); break; case RESETSERVER: this.getMasterConnector().openServer(); break; default: throw new AnalysisException("Not support such Event : " + event.getEventCode().toString()); } } }