是什么阻碍了我的systemd用户计时器?

时间:2016-02-14 01:20:19

标签: linux systemd

我使用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超时。

     

Feb 13 15:03:45 HOSTNAME systemd [1878]:超时开始描述。

     

Feb 13 15:03:45 HOSTNAME systemd [1878]:作业PROGRAM.service / start失败,结果为'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

1 个答案:

答案 0 :(得分:1)

有效过程

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

  1. 使用systemd启动进程时,所有子进程(至少默认情况下)都属于同一组。

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

  3. 这是什么意思?

    timer description说:

      

    请注意,如果要在计时器过去时激活的单元已经激活,它将不会重新启动,而只是继续运行。

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

    为什么这有意义?!

    CRON正在做同样的事情。如果你的进程仍在运行,它就不会一遍又一遍地重启它(因为这只会填满内存并可能会破坏许多其他东西。)但是,CRON没有进程组的概念。因此,如果您的主进程确实死亡,则认为它可以重新启动它。

    什么是systemd解决方案?

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

    KillMode=process
    

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

      

    如果设置为process,则只会杀死主进程本身。

    你可能想测试一下它是否真的有用,因为根据文档说它没有说它会把整个群体视为死...但从我的经验来看,这是有效的。

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

    由于我不推荐KillMode,因此应该有另一种解决方案。事实上,你的所有进程要么有20分钟的运行时间(或者它们产生时剩余的时间),否则它们将阻止后续运行发生,这可能偶尔会好转,但肯定不会他们永远呆在那里。因此,编辑这些流程并确保它们在一段时间后退出。

    然而,在 long 之后,可能有必要终止这些进程并使用超时工具,因为如果进程本身不能只是退出,那么你所做的可能是最好的解决方案em>准时。虽然我建议一个小修改,即使用19分钟。对于超时,因为否则您可能会错过下一个启动窗口。

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