Java tutorial
/* * Copyright (C) 2010-2101 Alibaba Group Holding Limited. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.alibaba.otter.manager.biz.monitor.impl; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorCompletionService; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import org.apache.commons.lang.exception.ExceptionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.util.CollectionUtils; import com.alibaba.otter.manager.biz.config.alarm.AlarmRuleService; import com.alibaba.otter.manager.biz.config.channel.ChannelService; import com.alibaba.otter.manager.biz.monitor.AlarmRecovery; import com.alibaba.otter.manager.biz.monitor.Monitor; import com.alibaba.otter.shared.arbitrate.ArbitrateManageService; import com.alibaba.otter.shared.common.model.config.alarm.AlarmRule; import com.alibaba.otter.shared.common.model.config.alarm.AlarmRuleStatus; import com.alibaba.otter.shared.common.model.config.channel.ChannelStatus; import com.alibaba.otter.shared.common.utils.thread.NamedThreadFactory; /** * ???? <br/> * http://xxxx/monitor/monitor_trigger.htm?token=otter???otter?????jvm?? * * @author zebin.xuzb @ 2012-8-23 * @version 4.1.0 */ public class GlobalMonitor implements Monitor, InitializingBean, DisposableBean { protected static final Logger log = LoggerFactory.getLogger("monitorInfo"); private static final int DEFAULT_THREADS = 5; private int nThreads; private boolean needConcurrent = true; private boolean recoveryPaused = true; private ExecutorService executor; private AlarmRuleService alarmRuleService; private Monitor pipelineMonitor; private ChannelService channelService; private ArbitrateManageService arbitrateManageService; private AlarmRecovery restartAlarmRecovery; @Override public void explore() { Map<Long, List<AlarmRule>> rules = alarmRuleService.getAlarmRules(AlarmRuleStatus.ENABLE); if (!CollectionUtils.isEmpty(rules)) { if (needConcurrent) { concurrentProcess(rules); } else {// serialProcess(rules); } } else { log.warn("no enabled alarm rule at all. Check the rule setting please!"); } // ?? if (recoveryPaused) { List<Long> channelIds = channelService.listAllChannelId(); if (needConcurrent) { concurrentProcess(channelIds); } else {// serialProcess(channelIds); } } } private void concurrentProcess(Map<Long, List<AlarmRule>> rules) { ExecutorCompletionService completionExecutor = new ExecutorCompletionService(executor); List<Future> futures = new ArrayList<Future>(); for (Entry<Long, List<AlarmRule>> entry : rules.entrySet()) { final List<AlarmRule> alarmRules = entry.getValue(); futures.add(completionExecutor.submit(new Callable<Object>() { @Override public Object call() throws Exception { pipelineMonitor.explore(alarmRules); return null; } })); } List<Throwable> exceptions = new ArrayList<Throwable>(); int index = 0; int size = futures.size(); while (index < size) { try { Future<?> future = completionExecutor.take(); future.get(); } catch (InterruptedException e) { exceptions.add(e); } catch (ExecutionException e) { exceptions.add(e); } index++; } if (!exceptions.isEmpty()) { StringBuilder sb = new StringBuilder(exceptions.size() + " exception happens in global monitor\n"); sb.append("exception stack start :\n"); for (Throwable t : exceptions) { sb.append(ExceptionUtils.getStackTrace(t)); } sb.append("exception stack end \n"); throw new IllegalStateException(sb.toString()); } } private void serialProcess(Map<Long, List<AlarmRule>> rules) { for (Entry<Long, List<AlarmRule>> entry : rules.entrySet()) { List<AlarmRule> alarmRules = entry.getValue(); pipelineMonitor.explore(alarmRules); } } private void concurrentProcess(List<Long> channelIds) { ExecutorCompletionService completionExecutor = new ExecutorCompletionService(executor); List<Future> futures = new ArrayList<Future>(); for (final Long channelId : channelIds) { futures.add(completionExecutor.submit(new Callable<Object>() { @Override public Object call() throws Exception { ChannelStatus status = arbitrateManageService.channelEvent().status(channelId); if (status.isPause()) { restartAlarmRecovery.recovery(channelId); } return null; } })); } List<Throwable> exceptions = new ArrayList<Throwable>(); int index = 0; int size = futures.size(); while (index < size) { try { Future<?> future = completionExecutor.take(); future.get(); } catch (InterruptedException e) { exceptions.add(e); } catch (ExecutionException e) { exceptions.add(e); } index++; } if (!exceptions.isEmpty()) { StringBuilder sb = new StringBuilder(exceptions.size() + " exception happens in global monitor\n"); sb.append("exception stack start :\n"); for (Throwable t : exceptions) { sb.append(ExceptionUtils.getStackTrace(t)); } sb.append("exception stack end \n"); throw new IllegalStateException(sb.toString()); } } private void serialProcess(List<Long> channelIds) { for (Long channelId : channelIds) { ChannelStatus status = arbitrateManageService.channelEvent().status(channelId); if (status.isPause()) { restartAlarmRecovery.recovery(channelId); } } } @Override public void afterPropertiesSet() throws Exception { nThreads = nThreads <= 0 ? DEFAULT_THREADS : nThreads; executor = new ThreadPoolExecutor(nThreads, nThreads, 0, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(nThreads * 2), new NamedThreadFactory("global monitor", false), new ThreadPoolExecutor.CallerRunsPolicy()); } @Override public void destroy() throws Exception { if (executor != null && !executor.isShutdown()) { executor.shutdown(); } } @Override public void explore(Long... pipelineIds) { throw new UnsupportedOperationException("doesn't support right now"); } @Override public void explore(List<AlarmRule> rules) { throw new UnsupportedOperationException("doesn't support right now"); } // ============== setter ============== public void setnThreads(int nThreads) { this.nThreads = nThreads; } public void setNeedConcurrent(boolean needConcurrent) { this.needConcurrent = needConcurrent; } public void setAlarmRuleService(AlarmRuleService alarmRuleService) { this.alarmRuleService = alarmRuleService; } public void setPipelineMonitor(Monitor pipelineMonitor) { this.pipelineMonitor = pipelineMonitor; } public void setChannelService(ChannelService channelService) { this.channelService = channelService; } public void setArbitrateManageService(ArbitrateManageService arbitrateManageService) { this.arbitrateManageService = arbitrateManageService; } public void setRestartAlarmRecovery(AlarmRecovery restartAlarmRecovery) { this.restartAlarmRecovery = restartAlarmRecovery; } public void setRecoveryPaused(boolean recoveryPaused) { this.recoveryPaused = recoveryPaused; } }