配置有问题的 systemd 服务以通过 SIGKILL 终止

Clo*_*oud 22 linux signals service systemd

背景

我被要求systemd为新服务创建一个脚本,该脚本foo_daemon有时会进入“不良状态”,并且不会通过SIGTERM(可能是由于自定义信号处理程序)而死亡。这对开发人员来说是有问题的,因为他们被指示通过以下方式启动/停止/重新启动服务:

  • systemctl start foo_daemon.service
  • systemctl stop foo_daemon.service
  • systemctl restart foo_daemon.service

问题

有时,由于foo_daemon进入不良状态,我们不得不通过以下方式强行杀死它:

  • systemctl kill -s KILL foo_daemon.service

我如何设置我的systemd脚本,foo_daemon以便每当用户尝试停止/重新启动服务时,systemd将:

  • 尝试正常关闭foo_daemonvia SIGTERM
  • 最多给 2 秒的时间foo_daemon来完成关闭/终止。
  • 如果进程仍然存在foo_daemonSIGKILL则尝试强制关闭via (因此我们没有 PID 被回收的风险以及错误 PID 的systemd问题SIGKILL)。我们正在测试的设备会快速生成/分叉多个进程,因此对于 PID 回收导致问题存在罕见但非常真实的担忧。
  • 如果在实践中,我只是对 PID 回收感到偏执,那么我可以接受脚本只是SIGKILL针对进程的 PID发出,而不必担心杀死回收的 PID。

Mic*_*ton 29

systemd 已经开箱即用地支持此功能,并且默认情况下启用

您可能想要自定义的唯一一件事是超时,您可以使用TimeoutStopSec=. 例如:

[Service]
TimeoutStopSec=2
Run Code Online (Sandbox Code Playgroud)

现在,systemd 将发送一个 SIGTERM,等待两秒钟让服务退出,如果没有,它将发送一个 SIGKILL。

如果您的服务不支持 systemd,您可能需要使用PIDFile=.

最后,您提到您的守护进程会产生许多进程。在这种情况下,您可能希望设置KillMode=control-group并且 systemd 将向 cgroup 中的所有进程发送信号。

  • @DevNull systemd 不创建或管理 PID 文件。没有理由这样做。如果你的服务没有创建自己的 PID 文件,那么如果可能的话,将它配置为在前台运行(而不是守护进程)并在 systemd 单元中设置 `Type=simple`。 (4认同)