配置越野车systemd服务以通过SIGKILL终止


20

背景

我被要求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_daemonvia SIGKILL(这样我们就不会有PID被回收的风险,也不会出现针对错误PID的systemd问题SIGKILL)。我们正在测试的设备迅速产生/分叉了许多过程,因此,对于PID回收引起问题的问题很少,但确实存在。
  • 如果实际上,我只是对PID回收抱有偏执,那么我可以接受脚本,只是SIGKILL针对进程的PID 发出脚本,而不必担心杀死回收的PID。


2
即使您快速生成进程以在两秒钟内滚动超过400万个PID,systemd 也不会循环检查“此pid仍然有效吗?此pid仍然有效吗?”。因为它并不需要到; 它已经被告知其直接子进程是否仍然有效(通过普通的SIGCHLD和waitpid())。因此,如果发现该进程在SIGTERM之后退出,那么它将在该点将服务标记为“非活动”,这完全不会打扰检查,等待和发送SIGKILL。
grawity

Answers:


26

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

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

[Service]
TimeoutStopSec=2

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

如果您的服务不支持systemd,则可能需要使用来提供其PID文件的路径PIDFile=

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


谢谢。最后一个问题:让我们假设该服务不是系统感知的。我可以在此服务的systemd脚本中添加些什么,以便systemd创建/管理PID文件?此外,该服务可以通过模板单元进行多实例操作,因此我们通常通过“ systemctl start foo_dameon@1.service”启动该服务,这样会影响脚本中的PID文件逻辑吗?
Cloud

4
@DevNull systemd不创建或管理PID文件。没有理由这样做。如果您的服务没有创建自己的PID文件,则尽可能将其配置为在前台运行(而不是守护进程)并Type=simple在systemd单元中进行设置。
迈克尔·汉普顿

1
如果该服务具有依赖关系,则Type=forking具有的优势是(如果该服务编写正确)在完全“就绪”时通知Systemd Type = simple无法完成。即使没有PID文件,守护进程也不成问题– systemd仍将跟踪主进程。
grawity

1
@grawity确实如此……尽管根据我的经验,服务实际上要准备好开始服务之前就进行守护进程。使用systemd-aware服务Type=notify最适合systemd,许多常见服务已经做到了。但可能不是此旧服务。在OP的情况下,他提供的服务会产生许多流程。系统文档警告这种情况
迈克尔·汉普顿

1

既然没有人提到过need Type=oneshot,这是一个完整的示例,由于超时失败而退出。

[Unit]
Description=timeout test

[Service]
Type=oneshot
TimeoutStartSec=2
ExecStart=/bin/sleep 10
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.