实现一个 Yarn Application, 如果想在被kill时做些什么的话,该怎么办?
也许,你正在这样做,或者已经这样做却发现不起作用
public abstract class YarnApplicationImpl implements AMRMClientAsync.CallbackHandler {
@Override
public void onShutdownRequest() {
//do something what you want to do
}
}
原想只要实现了这个回调,就会在用户发出 kill 命令时触发onShutdownRequest(), 然后我们就可以做些工作了,但是结果却是,这个方法压根不会执行,除非你的App在运行的过程中出现了异常,Yarn 不得不重启 AppLicationMaster 来完成任务(当然是在允许的失败次数以内),重启之前的关闭会向 AppLicationMaster 发送 kill 命令,触发onShutdownRequest(),而且这个方法的实现不能向 Yarn ResourceManager 注销自己除非下次不再启动。
所以,onShutdownRequest()这个方法只在 AppLicationMaster 重启的时候才会用到,不满足我们的需求。
其实,还有一个JDK自带的ShutdownHook
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
//do something what you want to do
}
});
不过,如果你在Windows上测试这个,还真是不管用。无论是通过windows的任务管理器还是通过taskkill命令。目前的试验下来,windows的“天才”逻辑让人费解,它的所有结束任务的方式都是像linux的kill 9一样,是一种强制结束任务的方式。所以addShutdownHook基本上没有机会被调用。
上面说的也不用担心,反正你又不在Windows上跑 Yarn.
好吧,决定用这个钩子,但是有一点必须注意,这里的代码不能太耗时,Yarn 在kill 一个Application 时,会先发送kill -15,接着就是kill -9,这就意味着你要尽可能快地退出jvm.