gpt4 book ai didi

linux - 是什么在拖延我的 systemd 用户计时器?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:12:12 25 4
gpt4 key购买 nike

我使用 systemd 用户计时器代替 cron。我有一个特定的程序设置为每 20 分钟执行一次。该程序不是守护进程,依赖于网络,并启动许多子进程。但是我注意到计时器经常在几个小时(或几天)后停止。计时器仍处于事件状态,但程序不再每 20 分钟执行一次。 pgrep 显示许多进程仍然处于事件状态。观察到这一点后,我将 JobTimeoutSec=3m 添加到 .service 文件中,希望进程在超时时会被杀死。

systemctl status --user PROGRAM.service 现在输出以下内容,但是子进程仍在运行并且计时器不再每 20 分钟执行一次程序:

Feb 13 15:03:45 HOSTNAME systemd[1878]: Job PROGRAM.service/start timed out.

Feb 13 15:03:45 HOSTNAME systemd[1878]: Timed out starting DESCRIPTION.

Feb 13 15:03:45 HOSTNAME systemd[1878]: Job PROGRAM.service/start failed with result 'timeout'.

我猜测该程序的子进程由于网络问题而停止,而 systemd 无法在超时时终止它们。

对于解决此问题以使计时器按预期继续运行有什么建议吗?

ExecStart=/path/to/program 替换为 ExecStart=/usr/bin/timeout 20m/path/to/program 似乎可以解决这个问题,但我'我想找出为什么单独使用 systemd 不行。


调试信息

PROGRAM.service

[Unit]
Description=DESCRIPTION
After=network.target
PartOf=network-online.target
JobTimeoutSec=3m

[Service]
Type=oneshot
ExecStart=/path/to/program

[Install]
WantedBy=network-online.target

PROGRAM.timer

[Unit]
Description=Run PROGRAM.service every 20 minutes

[Timer]
OnCalendar=*:0/20

[Install]
WantedBy=timers.target

systemd --version 输出如下:

systemd 219

+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT -GNUTLS +ACL +XZ -LZ4 -SECCOMP +BLKID -ELFUTILS +KMOD -IDN

最佳答案

事件进程

systemd 中有两件重要的事情,我认为你在这种情况下会碰到:

  1. 当您使用 systemd 启动进程时,所有子进程(至少在默认情况下)都是同一组的一部分。

  2. 如果这些 child 中的任何一个没有死亡,则认为该进程仍在(至少在某种程度上)运行。

这是什么意思?

timer description说:

Note that in case the unit to activate is already active at the time the timer elapses it is not restarted, but simply left running.

换句话说,如果您的任何一个进程在 20 分钟后仍在运行,定时器系统将不会重新启动任何东西。

为什么这是有道理的?!

CRON 正在做完全相同的事情。如果您的进程仍在运行,它不会一遍又一遍地重新启动它(因为那只会填满内存并可能破坏许多其他东西。)但是,CRON 没有进程组的概念。因此,如果您的主进程确实终止了,它会假定它可以重新启动它。

systemd 解决方案是什么?

假设您不能只停止子进程(虽然因为您使用了 /usr/bin/timedout,您可能可以?),一种方法是使用 KillMode选项,虽然我不推荐它:

KillMode=process

这意味着一旦主进程死亡,就认为服务停止了。

If set to process, only the main process itself is killed.

您可能想测试它是否真的有效,因为根据文档,它没有说它会认为整个组都死了......但根据我的经验,它有效。

那什么是更好的解决方案?

因为我不推荐KillMode,所以应该有另一种解决方案。事实上,您所有的进程要么有 20 分钟的运行时间(或者它们生成时剩余的任何时间),要么它们将阻止后续运行的发生,这偶尔可能没问题,但肯定不是如果他们永远留在身边。因此,需要编辑这些流程并确保它们在一段时间后退出。

但是,在很长一段时间后,可能有必要终止这些进程,如果进程本身不能退出,那么像您所做的那样使用超时工具可能是最好的解决方案准时。尽管我会建议一个小的修改,即使用 19 分钟。超时,否则您可能会错过下一个启动窗口。

ExecStart=/usr/bin/timeout 19m /path/to/program

关于linux - 是什么在拖延我的 systemd 用户计时器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35387345/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com