概述
submitApplication会经历的event:launch类型的AMLaucherEvent
ApplicationMasterLauncher处理launch类型的AMLaucherEvent
ResourceManager的内部类RMActiveService为AsyncDispatcher注册AMLauncherEventType类型的处理器—— ApplicationMasterLauncher
protected void serviceInit(Configuration configuration) throws Exception {
applicationMasterLauncher = createAMLauncher();
rmDispatcher.register(AMLauncherEventType.class,
applicationMasterLauncher);
}
protected ApplicationMasterLauncher createAMLauncher() {
return new ApplicationMasterLauncher(this.rmContext);
}
ApplicationMasterLauncher处理AMLauncherEvent
//Runnable队列,通过队列可以在短时间内有大量launch AM的事件提交时起到缓冲作用
private final BlockingQueue<Runnable> masterEvents
= new LinkedBlockingQueue<Runnable>();
@Override
public synchronized void handle(AMLauncherEvent appEvent) {
AMLauncherEventType event = appEvent.getType();
RMAppAttempt application = appEvent.getAppAttempt();
switch (event) {
case LAUNCH:
launch(application);
break;
case CLEANUP:
cleanup(application);
break;
default:
break;
}
}
private void launch(RMAppAttempt application) {
//生成AMLauncher
Runnable launcher = createRunnableLauncher(application,
AMLauncherEventType.LAUNCH);
//添加到runnable队列
masterEvents.add(launcher);
}
LauncherThread处理Runnable队列中的AMLauncher
private ThreadPoolExecutor launcherPool;
private class LauncherThread extends Thread {
public LauncherThread() {
//线程名
super("ApplicationMaster Launcher");
}
@Override
public void run() {
while (!this.isInterrupted()) {
Runnable toLaunch;
try {
//从Runnable队列中取出一个AMLauncher
toLaunch = masterEvents.take();
//将AMLauncher放入线程池中执行
launcherPool.execute(toLaunch);
} catch (InterruptedException e) {
LOG.warn(this.getClass().getName() + " interrupted. Returning.");
return;
}
}
}
}
AMLauncher的run()方法逻辑
public void run() {
switch (eventType) {
case LAUNCH:
try {
LOG.info("Launching master" + application.getAppAttemptId());
//与NM通信,启动ApplicationMaster
launch();
//启动成功后,向RMAppAttemptImpl发送RMAppAttemptEventType.LAUNCHED事件
handler.handle(new RMAppAttemptEvent(application.getAppAttemptId(),
RMAppAttemptEventType.LAUNCHED, System.currentTimeMillis()));
} catch(Exception ie) {
onAMLaunchFailed(masterContainer.getId(), ie);
}
break;
default:
LOG.warn("Received unknown event-type " + eventType + ". Ignoring.");
break;
}
}
AMLauncher的launch()方法
private void launch() throws IOException, YarnException {
connect();
ContainerId masterContainerID = masterContainer.getId();
ApplicationSubmissionContext applicationContext =
application.getSubmissionContext();
LOG.info("Setting up container " + masterContainer
+ " for AM " + application.getAppAttemptId());
//创建ContainerLaunchContext,里面包含着启动AM要执行的命令
ContainerLaunchContext launchContext =
createAMContainerLaunchContext(applicationContext, masterContainerID);
//创建startContainerRequest,AM是NM端启动的第一个contaienr,由RM发起
//以后的startContainerRequest都由AM发起
StartContainerRequest scRequest =
StartContainerRequest.newInstance(launchContext,
masterContainer.getContainerToken());
List<StartContainerRequest> list = new ArrayList<StartContainerRequest>();
list.add(scRequest);
//rpc请求的消息格式是StartContainersRequest
StartContainersRequest allRequests =
StartContainersRequest.newInstance(list);
//代理发起rpc请求
StartContainersResponse response =
containerMgrProxy.startContainers(allRequests);
if (response.getFailedRequests() != null
&& response.getFailedRequests().containsKey(masterContainerID)) {
Throwable t =
response.getFailedRequests().get(masterContainerID).deSerialize();
parseAndThrowException(t);
} else {
LOG.info("Done launching container " + masterContainer + " for AM "
+ application.getAppAttemptId());
}
}
NM端startContainer
略,请参阅下一篇博客:yarn3.2源码分析之NM端startContainer事件流程