supervisord 停止子进程

Posted

技术标签:

【中文标题】supervisord 停止子进程【英文标题】:supervisord stopping child processes 【发布时间】:2012-02-23 19:54:51 【问题描述】:

supervisord 面临的一个问题是,当我有一个命令生成另一个进程时,supervisord 无法杀死它。

例如,我有一个 java 进程,当它正常运行时就像

 $ zkServer.sh start-foreground
 $ ps -eaf | grep zk
 user 30404 28280  0 09:21 pts/2    00:00:00 bash zkServer.sh start-foreground
 user 30413 30404 76 09:21 pts/2    00:00:10 java -Dzookeeper.something..something

supervisord 配置文件如下所示:

[program:zookeeper]
command=zkServer.sh start-foreground
autorestart=true
stopsignal=KILL

在从supervisorctl 阻止它们时,supervisord 无法很好地处理这些具有多个子进程的进程。因此,当我从 supervisord 运行它并尝试从 supervisorctl 停止它时,只有***进程被杀死,而不是实际的 java 进程。

【问题讨论】:

据我了解,systemdinit-replacement 使用cgroups 可以可靠地跟踪子进程。它可能适合您的需求。 【参考方案1】:

Rick Hanlon II 在这里遇到了同样的问题:https://coderwall.com/p/4tcw7w

选项 stopasgroup=true 应该在程序部分设置为 supervisord 不仅停止父进程而且停止子进程。

示例如下:

[program:some_django]
 command=python manage.py runserver
 directory=/dir/to/app
 stopasgroup=true

另外,请记住,您可能有一个较旧的 supervisord 包,它没有“stopasgroup”功能。 我在 Raspberry Pi 上尝试了这些 Debian 软件包:

supervisor_3.0a8 不起作用。 supervisor_3.0b2-1 按预期工作。

【讨论】:

另请注意,supervisord 不会自动进行配置更改。您需要运行 supervisorctl update 以将更改应用到您的配置,或重新启动 supervisord 进程。 这应该是默认选项。 这对我来说非常适合主管 3.2。谢谢。【参考方案2】:

在 supervisord 调用的主 bash 脚本中尽早执行以下操作为我解决了这个问题:

trap "kill -- -$$" EXIT

这会在主脚本退出时杀死整个进程组,例如当它被 supervisord 杀死时。

【讨论】:

【参考方案3】:

最近向 supervisord 添加了一项功能,用于向整个进程组发送 SIGKILL。它在github,但尚未正式发布。

如果进程ID在文件中可用,您可以使用pid-proxy program

【讨论】:

【参考方案4】:

试试这个主管程序配置:

stopasgroup=true
killasgroup=true
stopsignal=INT

【讨论】:

【参考方案5】:

下面的文章对这个问题有深入的讨论:

http://veithen.github.io/2014/11/16/sigterm-propagation.html

【讨论】:

exec ... 为我解决了这个问题。文章中的第一个选项。谢谢 感谢您教导如何捕鱼而不是提供鱼 ;)【参考方案6】:

您也可以在/conf.d/your-configuration.conf 文件中使用优先级。例如,如果你想先运行zookeeper,然后运行kafka,你可以指定两个程序。

低优先级意味着程序先启动最后停止。

【讨论】:

以上是关于supervisord 停止子进程的主要内容,如果未能解决你的问题,请参考以下文章

supervisord 进程管理利器

supervisord的使用用法

supervisor 配置篇

重新加载 supervisord 会导致其下的进程停止吗?

Supervisord管理进程常用命令

logstash使用supervisord