package com.taobao.top.analysis.node.component; import java.util.Collection; import java.util.Date; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.taobao.top.analysis.config.SlaveConfig; import com.taobao.top.analysis.exception.AnalysisException; import com.taobao.top.analysis.node.connect.ISlaveConnector; import com.taobao.top.analysis.node.event.SendMonitorInfoEvent; import com.taobao.top.analysis.node.job.JobTaskExecuteInfo; import com.taobao.top.analysis.node.monitor.IMonitor; import com.taobao.top.analysis.node.monitor.MonitorUtil; import com.taobao.top.analysis.node.monitor.SlaveMonitorInfo; import com.taobao.top.analysis.util.NamedThreadFactory; /** * Slave端口的监控器 * @author sihai * */ public class SlaveMonitor implements IMonitor<SlaveConfig> { private static final Log logger = LogFactory.getLog(SlaveMonitor.class); /** * Slave配置信息 */ private SlaveConfig config; /** * Slave监控信息 */ private SlaveMonitorInfo monitorInfo; /** * 通信层组件 */ private ISlaveConnector slaveConnector; /** * 定时汇报 */ private ScheduledExecutorService executor; private long idGenerator = 0; @Override public SlaveConfig getConfig() { return config; } @Override public void init() throws AnalysisException { monitorInfo = new SlaveMonitorInfo(); monitorInfo.setSlaveStartupTime(new Date()); executor = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("Slave-Monitor", true)); executor.scheduleWithFixedDelay(new ReportTask(), config.getSlaveReportMonitorInterval() * 2, config.getSlaveReportMonitorInterval(), TimeUnit.SECONDS); } @Override public void releaseResource() { executor.shutdownNow(); } @Override public void setConfig(SlaveConfig config) { this.config = config; } /** * 统计一次任务拉取的情况 * @param time */ public void putPullTaskConsumeTime(long time, int taskCount) { monitorInfo.setSlavePullTaskConsumeTime(monitorInfo.getSlavePullTaskConsumeTime() + time); monitorInfo.setSlaveTryPullTaskCount(monitorInfo.getSlaveTryPullTaskCount() + 1); monitorInfo.setSlavePulledTaskCount(monitorInfo.getSlavePulledTaskCount() + taskCount); monitorInfo.setAveragePullTaskConsumeTime(monitorInfo.getSlavePullTaskConsumeTime() / (monitorInfo.getSlaveTryPullTaskCount() + 0.0D)); monitorInfo.setAveragePulledTaskCount(monitorInfo.getSlavePulledTaskCount() / (monitorInfo.getSlaveTryPullTaskCount() + 0.0D)); } /** * * @param count */ public void incPulledTaskCount(long count) { // monitorInfo的slavePulledTaskCount声明为volatile能保证线程安全, 只有一个线程修改slavePulledTaskCount, 一个线程读取 monitorInfo.setSlavePulledTaskCount(monitorInfo.getSlavePulledTaskCount() + count); } /** * 任务执行统计 * @param count */ public void executedTask(long time, Collection<JobTaskExecuteInfo> infoList) { logger.warn(String.format("executedTask, time=%d, infoList.size=%d", time, infoList.size())); long dataSize = 0; long line = 0; long emptyLine = 0; long exceptionLine = 0; long keyCount = 0; long valueCount = 0; for(JobTaskExecuteInfo info : infoList) { dataSize += info.getJobDataSize(); line += info.getTotalLine(); emptyLine += info.getEmptyLine(); exceptionLine += info.getErrorLine(); keyCount += info.getKeyCount(); valueCount += info.getValueCount(); } // 增加执行时间 monitorInfo.incSlaveExecuteTaskTime(time); // 增加完成的任务数量 monitorInfo.incSlaveExecutedTaskCount(infoList.size()); // 增加消耗的数据量 monitorInfo.incSlaveConsumeDataSize(dataSize); // 增加消耗的数据行 monitorInfo.incSlaveConsumeDataLine(line); // 增加消耗的空数据行 monitorInfo.incSlaveConsumeEmptyLine(emptyLine); // 增加消耗的异常数据行 monitorInfo.incSlaveConsumeExceptionLine(exceptionLine); // 增加产生的key数量 monitorInfo.incKeyCount(keyCount); // 增加产生的value数量 monitorInfo.incValueCount(valueCount); } /** * 任务merge统计 * @param time * @param taskCount */ public void mergedTask(long time, long taskCount) { monitorInfo.incMergedTaskCount(taskCount); monitorInfo.incMegeredTaskConsumeTime(time); } public void setSlaveConnector(ISlaveConnector slaveConnector) { this.slaveConnector = slaveConnector; } private class ReportTask implements Runnable { @Override public void run() { try { SendMonitorInfoEvent event = new SendMonitorInfoEvent("monitor-info-" + idGenerator++); event.setSlaveMonitorInfo((SlaveMonitorInfo)monitorInfo.clone()); MonitorUtil.monitor(event.getSlaveMonitorInfo()); slaveConnector.sendMonitorInfo(event); } catch (CloneNotSupportedException e) { logger.error("Exception:", e); } } } }