我在EC2现场实例上运行一些应用程序。 没有任何通知,亚马逊可能会杀死这种情况。
在关机过程中,进程以某种顺序被终止。 我们有监视/恢复程序,根据服务器是closures还是进程崩溃,应该有不同的performance。 (具体而言,如果服务器实际上正在closures,我们不想做任何事情)
如何在恢复过程中检测到(如果它仍然存在)进程因为关机而中止?
(更多系统细节:我在不修改外部状态的沙箱中运行未知/不可信/ etc代码,一般情况下,如果沙箱代码崩溃,那么是不可信代码作者的错误,我们不会重新运行。由于虚拟机closures或失败,沙盒代码被终止,我们需要在另一个实例上重新运行它。我现在遇到的问题是用户的代码被首先终止,所以监视程序错误地认为崩溃是用户错误。)
在生成沙箱子进程的每台计算机上运行代理。 代理程序运行您的代码是“防止崩溃”,沙箱代码运行可能会崩溃的用户代码。
负责使用新沙盒进程启动新计算机的监视系统会检查哪些进程已被杀死(代理和沙箱进程或只有沙箱子进程)。
它通过打开TCP连接(RMI / RPC / HTTP)来查询子进程的代理。 如果代理响应 – 计算机仍在运行,可能会询问其子沙盒进程。 如果代理没有响应 – 机器怀疑被终止。
代理还负责在同一台虚拟机上重新启动子沙箱进程,以防发生崩溃。
使用查找服务(如Zoo Keeper)跟踪哪些进程发送心跳保持活动。 如果代理程序处于活动状态,则机器仍在运行,如果代理程序未处于活动状态,则代理程序未运行。
轮询EC2 API以确定机器是否处于运行或终止状态。
你的恢复过程如何工作?
如果您使用waitpid
来监控进程,则在退出时可以确定:
根据进程关闭的方式,我希望看到它正常退出或通过SIGTERM
或SIGKILL
退出。 SIGILL
, SIGABRT
, SIGFPE
, SIGBUS
, SIGSEGV
和SIGSYS
会显示编程错误的崩溃。
这听起来像一个非常脆弱的计划。 不要尝试检测系统的状态:让应用程序在应用程序的“干净”关闭/暂停/停止之后以某种方式写出有效性令牌(并同步相关文件!)并使用该令牌。
我假设当实例关闭时,您的监控进程将收到一个SIGTERM信号。
所以有可能做这样的事情 – 如果受监视的进程已经退出&&在接下来的5秒内没有收到SIGTERM信号 – 假设进程崩溃。 如果收到SIGTERM,只需从信号处理程序中退出即可。