新贵和多信号关闭过程

新贵和多信号关闭过程

我正在 Ubuntu 上运行 resque 工作服务,并且我想使用 upstart (Ubuntu 的默认进程管理器)来管理它。

resque 工作线程的正确关闭顺序是QUIT首先发送信号,然后等待进程首先完成任何正在运行的作业。然后它应该会自行停止。如果工作进程没有及时关闭 - 因为作业仍在运行(可能被卡住),我需要发送一个TERM信号,这将导致工作进程中止作业并退出。显然,如果这不起作用,则KILL必须发送信号。

我认为实现此目的的方法是发送pre-start script信号QUIT,然后休眠,直到进程存在或超时到期。

但实际上发生的情况是,如果工作人员响应QUIT并退出,respawn则启动并重新启动进程,这显然会导致停止进程不会发生。

如果我们无论如何都要停止进程,有没有办法让暴发户不重生?

答案1

我发现有两种方法可以解决这个问题,但都不是完美的:

  1. 新贵有kill signal节。如果您kill signal QUIT同时设置了 和kill timeout 600,Upstart 将发送SIGQUIT给该​​进程,然后等待 600 秒后再发送SIGKILL。如果进程在SIGKILL发送之前终止,那么我们就可以了。这种方法存在一些问题:(a)它发送SIGKILL而不是SIGTERM在超时后发送,这不允许 resque 工作人员很好地关闭,但这没什么大不了的。 (b) 我发现的一个更糟糕的问题是 upstartSIGQUIT向会话中的所有进程发送“kill 信号”(在我们的例子中),这可能会干扰 resque 工作线程的子进程的操作(SIGQUIT默认操作是终止带有核心转储)。
  2. 实现您自己的包装器,捕获您配置的暴发户发送的任何信号(或仅假设默认值SIGTERM)并自行处理所有正常关闭。在这种情况下,将 Upstart 设置kill timeout为足够的时间非常重要,以便让您的包装器正常关闭,并在时间到了时强制中止(在这种情况下,请确保超时时间略小于 Upstart 的超时时间),或者只是依赖UpstartSIGKILL用于清理(这可能是也可能不是一个好主意,具体取决于您的要求)。缺点:要做到这一点相当复杂,Upstart 存在的原因是这样您就不必为每个服务自己编写流程管理器。

如果您不想采用任何一种方式,还有其他流程管理器可能会实现比 Upstart 支持更复杂的信号机制,并且这些通常很容易在 Upstart 下实现,以管理您遇到问题的流程。不幸的是,很难找到一种在所有情况下都能正常工作的方法。例如我尝试过蓝药丸,在纸面上看起来很棒,但在撰写本文时有一个明显的错误,如果您尝试具有多个信号和多个超时的复杂信号机制,它只会一次发送所有信号(不一定以正确的顺序)并使子进程。

如果其他人有更多信息要添加,请随意添加更多答案,如果它很好的话,我什至可以将其标记为“已回答”(而不是我的自我回答)。

答案2

来自暴发户食谱:

由于运行预停止时作业的目标已经是“停止”,因此您可以通过任何方式关闭该进程,并且该进程不会重新生成(即使使用重生节)。

您可以尝试发送脚本的部分QUITpre-stop

相关内容