在处理使用文件锁定的解决方案时,我认为我的代码陷入了死锁。我正在使用 systemd 在系统启动时启动该进程。使用 alarm(3) 是一种选择,但我想知道 systemd 是否有办法检测挂起的进程并重新启动它们?
目前,为了暂时解决这个问题,我打算查看 journalctl 输出,如果它在指定的时间内没有改变,那么我将通过 shell 脚本终止该进程。
只是想知道是否有更好的方法通过 systemd 或其他方式监控进程。
答案1
是的;但是在摆弄 systemd 之前,请先修复您的有缺陷的程序。
MariusMatutiae 说得很对。你的程序有问题。它死锁了。摆弄 systemd 不是解决办法。充其量,它只是分散注意力。修复你的程序,让它不坏。把你的精力用在正确的事情上。
话虽如此,其他人还是会因为问题标题而不是问题本身而来到这里。为了方便他们,以下是标题的答案,忽略问题本身:
是的,systemd 可以监控守护进程,并在它们停止通信时自动重新启动它们。但并不是任何旧的守护进程都可以。正如 mvp 所指出的,没有办法知道守护进程是否已挂起(至少在这个停机问题无法判定的世界中)。systemd 或任何其他计算机程序都无法从头推断出某个随机程序是否已死锁、陷入无限循环或其他什么原因。您在这里能得到的最好的结果是检测到守护进程未在要求的时间范围内执行常规“心跳”操作。
因此,利用 systemd 看门狗功能的守护进程必须编写为使用 systemd 特定的协议,即 sd_notify 协议。这会使守护进程代码稍微复杂一些。这进一步复杂化,因为如果编写正确,守护进程还应该检查它们是否在启用看门狗功能的情况下被调用。
使用此协议的守护进程可以利用 systemd 的看门狗功能……
- …必须检查
WATCHDOG_USEC
环境变量; - …必须打电话sd_notify()在其整个生命周期内,持续且频繁地
WATCHDOG=1
设置选项,间隔约为WATCHDOG_USEC
/2(“USEC”代表微秒); - … 一定有
Type=notify
在其单元文件中设置; - … 应该有
NotifyAccess=main
(或=all
)在其单元文件中设置; - … 一定有
WatchdogSec=
秒在其单元文件中设置。 - …必须链接到
libsystemd-daemon.so
如果你想知道编码的细节,在阅读手册后,一定要去正确的 StackExchange。这是 SuperUser。StackOverflow 是在那边。
进一步阅读
- Lennart Poettering。2011-04-12。 监察者。 Freedesktop.org。