概述
在RM进程内,有两个关于AMLivelinessMonitor的服务被添加到了服务列表里面,一个是amLivelinessMonitor,另一个是amFinishingMonitor。AMLivelinessMonitor实现了AbstractLivelinessMonitor<ApplicationAttemptId>(从这里可以看出一个AM对应一个ApplicationAttempt),此对象又实现了AbstractService,所以它本质是一个service。
amLivelinessMonitor
AM如何被添加入amLivelinessMonitor内部的监控列表呢?我们现在来看代码。AbstractLivelinessMonitor<ApplicationAttemptId>里面有两个地方可以添加进内部列表,一个是receivedPing,一个就是register。先看第二个,我们通过Eclipse的Open Call Hierarchy,看到有五个地方调用了这个方法,一个一个分析,我们发现真正跟amLivelinessMonitor相关的是RMAppAttemptImpl的attemptLaunched方法。接着往上找,发现时AMLaunchedtransition的transition调用的,这肯定跟状态机有关了,找到状态机以后,发现是接受到RMAppAttemptEventType.LAUNCHED事件的时候,调用的。这个事件是用户提交应用程序后,经过一定的事件流转,流转到这里来的。同时,状态会从ALLOCATED变成LAUNCHED。也就是说,当用户提交了应用程序后,应用程序的AM会被添加入amLivelinessMonitor的内部列表内,剩下的就是去定期check是否过期了,这个逻辑在服务库里面会讲到。第一个,AM心跳的时候会调用ApplicationMasterService的allocate的时候会调用receivedPing。
剩下的一个问题就是,一旦监听器发现AM过期了,会做什么处理呢?我们都知道,一旦过期,监听器会调用amLivelinessMonitor的expire方法,这个方法里面发送了RMAppAttemptEventType.EXPIRE事件,这个事件最后会转给RMAppAttemptImpl处理。状态机会调用ExpiredTransition.transition,它干了什么呢?它干了如下的事情:
- 设置当前的appAttempt的progress是1.0f,不知道这个是做什么用的,怀疑这个意思是标记当前的进度为100%!
- 然后通知ApplicationMasterService去unregisterAttempt。如何做这件事情,我们在ApplicationMasterService里面讲。
- 底下是个switch,我们的肯定是FILLED啦。FILLED里面做了两件事,通知appAttempt别把AM的URL丢了,然后生成了一个类型为RMAppEventType.ATTEMPT_FAILED的事件。
- 发送这个事件出去,此事件被RMAppImpl捕获(大致逻辑是,如果AM被RM管控,并且需要retry,那么就重新启动一个AppAttempt,否则通知RMNodeImpl清理,移除state store,通知RMAppManager程序完成)。然后在发送一个SchedulerEventType.APP_REMOVED出去,此事件被ResourceScheduler(大致逻辑是,application上面的所有container全部标记为KILL,等NM心跳后,告诉NM去干掉他们,释放application上所有的release container,清空pending的请求和metrics,从叶子节点上结束application,删除掉appattemptid)捕获。
- 移除Credentials。(从ClientToAMTokenSecretManager中unregister,从AMRMTokenSecretManager中移除AppAttempt)
- 从amLivelinessMonitor内部列表中移除appAttempt,从amFinishingMonitor内部列表中移除appAttempt。
- 如果此AM收RM管控,则发送AMLauncherEventType.CLEANUP通知AMLauncher清理appAttempt(NM下次心跳的时候获取需要清理的Container,进行清理)。
amFinishingMonitor
TODO