package com.alipay.bluewhale.core.daemon.supervisor; import java.io.File; import java.util.Map; import java.util.UUID; import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; import org.apache.commons.io.FileUtils; import org.apache.log4j.Logger; import backtype.storm.utils.LocalState; import backtype.storm.utils.Utils; import com.alipay.bluewhale.core.cluster.Cluster; import com.alipay.bluewhale.core.cluster.Common; import com.alipay.bluewhale.core.cluster.StormClusterState; import com.alipay.bluewhale.core.cluster.StormConfig; import com.alipay.bluewhale.core.event.EventManager; import com.alipay.bluewhale.core.event.EventManagerImp; import com.alipay.bluewhale.core.messaging.ZMQContext; import com.alipay.bluewhale.core.utils.AsyncLoopThread; import com.alipay.bluewhale.core.utils.NetWorkUtils; import com.alipay.bluewhale.core.utils.SmartThread; import com.alipay.bluewhale.core.utils.TimeUtils; /** * supervisor ��Ҫ��������¼��������� * 1. ��zk��д���Լ�������supervisorInfo. Ŀǰû���ڼ�� * 2. ����һ���̣߳�ÿ��10sִ��SynchronizeSupervisor�� * (1) ����Ҫ���صĴ��롢jar���������ļ��� * (2) ɾ����Щû�б�nimbus���������topology��Դ�� * (3) ��nimbus���䵽��supervisor������д�뵽/storm-local-dir/supervisor/localstate�У� * LocalState���Կ�����һ��KV database; * (4) ��syncProcesses��ӵ���Ӧ���¼������С� * 3. ����һ���̣߳�ÿ��supervisor.monitor.frequency.secsִ��SyncProcesses�� * (1) �ر������쳣(�����ڣ���ʱ)��worker�� * (2) �ҳ���Ҫ������worker�������� */ public class Supervisor { private static Logger LOG = Logger.getLogger(Supervisor.class); // public String generateSupervisorId() { // return StormUtils.uuid().toString();// util.clj // } /** * ����һ��supervisor * * @param conf�� ������Ϣ��default.yaml storm.yaml * @param sharedContext�� Ŀǰ����ʱ����Ϊ null * @return SupervisorManger: �ɹر�supervisor�������е�worker */ public SupervisorManger mkSupervisor(Map conf, ZMQContext sharedContext) throws Exception { LOG.info("Starting Supervisor with conf " + conf); /** * Step 1: cleanup all files in supervisor_tmp_dir */ //���/storm-local-dir/supervisor/tmp �µ������ļ� String path = StormConfig.supervisorTmpDir(conf); FileUtils.cleanDirectory(new File(path)); AtomicBoolean active = new AtomicBoolean(true); int startTimeStamp = TimeUtils.current_time_secs(); //Step 2, get hostname //��������� String myHostName = NetWorkUtils.local_hostname(); ConcurrentHashMap<String, String> workerThreadPids = new ConcurrentHashMap<String, String>(); /* * Step 3: mk_storm_cluster_state register supervisor stats in zookeeper * 3.1 connection zk * 3.2 register watcher of zk * 3.3 register all kinds of callbacks * 3.4 create znode */ //�ɲ���zookeeper��ʵ�� StormClusterState stormClusterState = Cluster .mk_storm_cluster_state(conf); /* * Step 4, create LocalStat LocalStat is one KV database * 4.1 create LocalState instance * 4.2 get or put supervisorId */ //��supervisoridд�뱾�� LocalState localState = StormConfig.supervisorState(conf); String supervisorId = (String) localState.get(Common.LS_ID); if (supervisorId == null) { supervisorId = UUID.randomUUID().toString(); localState.put(Common.LS_ID, supervisorId); } /* * Step 5, create event manager EventManger create one thread to handle * event get one event from queue, then execute it */ /* * EventManager ���������ʱ�򣬻�����һ���������̻߳�ѭ�����¼�������ȡ��һ��ʱ�䣬��ִ�У� * eventManager����SynchronizeSupervisor��processesEventManager����SyncProcesses�� */ EventManager eventManager = new EventManagerImp(false); EventManager processesEventManager = new EventManagerImp(false); //Step 6, create syncProcess //SyncProcesses���ر������쳣(�����ڣ���ʱ)��worker���ҳ���Ҫ������worker�������� SyncProcesses syncProcesses = new SyncProcesses(supervisorId, conf, localState, workerThreadPids, sharedContext); //Step 7, create synchronizeSupervisor /* SynchronizeSupervisor * (1) ����Ҫ���صĴ��롢jar���������ļ��� * (2) ɾ����Щû�б�nimbus���������topology��Դ�� * (3) ��nimbus���䵽��supervisor������д�뵽/storm-local-dir/supervisor/localstate�У� * LocalState���Կ�����һ��KV database; * (4) ��syncProcesses��ӵ���Ӧ���¼������С� */ SynchronizeSupervisor synchronizeSupervisor = new SynchronizeSupervisor( supervisorId, conf, eventManager, processesEventManager, stormClusterState, localState, syncProcesses); //Step 8: create HeartBeat //��zk��д��һ��supervisor��������Ϣ Heartbeat hb = new Heartbeat(conf, stormClusterState, supervisorId, myHostName, startTimeStamp); hb.run(); //Step 9: start the threads Vector<SmartThread> threads = new Vector<SmartThread>(); //Step 9.1 start heartbeat thread //����һ���̣߳�ÿ��supervisor.heartbeat.frequency.secsд��һ��supervisor������Ϣ AsyncHeartbeat asyncHB = new AsyncHeartbeat(conf, hb, active); AsyncLoopThread heartbeat = new AsyncLoopThread(asyncHB, false, null, Thread.MAX_PRIORITY, true); threads.add(heartbeat); //Step 9.2 start sync Supervisor thread //����һ���̣߳�ÿ��10��ִ��SynchronizeSupervisor AsyncSynchronizeSupervisor syncSupervisor = new AsyncSynchronizeSupervisor( eventManager, synchronizeSupervisor, active); AsyncLoopThread syncsThread = new AsyncLoopThread(syncSupervisor); threads.add(syncsThread); // Step 9.3 start sync process thread //����һ���̣߳�ÿ��supervisor.monitor.frequency.secs��ִ��SyncProcesses AsyncSyncProcesses syncProcess = new AsyncSyncProcesses(conf, processesEventManager, syncProcesses, active); AsyncLoopThread syncpThread = new AsyncLoopThread(syncProcess, false, null, Thread.MAX_PRIORITY, true); threads.add(syncpThread); LOG.info("Starting supervisor with id " + supervisorId + " at host " + myHostName); //SupervisorManger�� �ɹر�supervisor�������е�worker return new SupervisorManger(conf, supervisorId, active, threads, processesEventManager, eventManager, stormClusterState, workerThreadPids); } /** * �ر�supervisor * @param supervisor */ public void killSupervisor(SupervisorManger supervisor) { supervisor.shutdown(); } /** * ����supervisor */ public void run() { SupervisorManger supervisorManager = null; try { Map conf = Utils.readStormConfig(); Common.validate_distribute_mode(conf); supervisorManager = mkSupervisor(conf, null); } catch (Exception e) { LOG.error("Failed to start supervisor\n", e); System.exit(1); } try { Thread.currentThread().join(); } catch (InterruptedException e) { LOG.info("Begin to shutdown supervisor"); supervisorManager.ShutdownAllWorkers(); supervisorManager.shutdown(); LOG.info("Successfully shutdown supervisor"); } } /** * supervisor daemon enter entrance * * @param args */ public static void main(String[] args) { Supervisor instance = new Supervisor(); instance.run(); } }