为什么 Systemd.timer 会在 OnCalendar 上暂停一段时间

为什么 Systemd.timer 会在 OnCalendar 上暂停一段时间

我使用 Systemd.Timer 每秒运行一次代码。但是 cronjob 运行得不太好。它每六七秒就会暂停一次。如下所示:

Sun Jul 28 18:49:34 CST 2019
Sun Jul 28 18:49:35 CST 2019
Sun Jul 28 18:49:36 CST 2019
Sun Jul 28 18:49:37 CST 2019
Sun Jul 28 18:49:38 CST 2019 --- paused
Sun Jul 28 18:49:45 CST 2019
Sun Jul 28 18:49:46 CST 2019
Sun Jul 28 18:49:47 CST 2019
Sun Jul 28 18:49:48 CST 2019
Sun Jul 28 18:49:49 CST 2019 --- paused
Sun Jul 28 18:49:55 CST 2019
Sun Jul 28 18:49:56 CST 2019
Sun Jul 28 18:49:57 CST 2019
Sun Jul 28 18:49:58 CST 2019
Sun Jul 28 18:49:59 CST 2019 --- paused ...
Sun Jul 28 18:50:06 CST 2019
Sun Jul 28 18:50:07 CST 2019
Sun Jul 28 18:50:08 CST 2019
Sun Jul 28 18:50:09 CST 2019
Sun Jul 28 18:50:10 CST 2019
Sun Jul 28 18:50:16 CST 2019
Sun Jul 28 18:50:17 CST 2019
Sun Jul 28 18:50:18 CST 2019
Sun Jul 28 18:50:19 CST 2019
Sun Jul 28 18:50:20 CST 2019
Sun Jul 28 18:50:27 CST 2019
Sun Jul 28 18:50:28 CST 2019
Sun Jul 28 18:50:29 CST 2019
Sun Jul 28 18:50:30 CST 2019
Sun Jul 28 18:50:31 CST 2019
Sun Jul 28 18:50:37 CST 2019
Sun Jul 28 18:50:38 CST 2019
Sun Jul 28 18:50:39 CST 2019

这是怎么造成的?有什么办法可以解决这个问题吗?

服务如下:

#testTimer.service
[Unit]
Description=my description

[Service]
ExecStart=echo `date` >> /tmp/timer.log

这是计时器:

#cal.timer
[Unit]
Description=my description

[Timer]
OnCalendar=*:*:0/1
Unit=test.service
Persistent=yes
AccuracySec=1us

[Install]
WantedBy=multi-user.target

这里是systemctl list-timers --all

NEXT                         LEFT          LAST                         PASSED       UNIT                         ACTIVATES
Tue 2019-07-30 10:41:09 CST  459ms left    Tue 2019-07-30 10:41:08 CST  540ms ago    cal.timer                    testTimer.service
Tue 2019-07-30 15:14:52 CST  4h 33min left Mon 2019-07-29 15:14:52 CST  19h ago      systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
Wed 2019-07-31 03:41:51 CST  17h left      Tue 2019-07-30 09:20:52 CST  1h 20min ago apt-daily.timer              apt-daily.service
Wed 2019-07-31 06:13:53 CST  19h left      Tue 2019-07-30 06:20:52 CST  4h 20min ago apt-daily-upgrade.timer      apt-daily-upgrade.service
n/a                          n/a           n/a                          n/a          snapd.refresh.timer
n/a                          n/a           n/a                          n/a          snapd.snap-repair.timer      snapd.snap-repair.service
n/a                          n/a           n/a                          n/a          ureadahead-stop.timer        ureadahead-stop.service

提前致谢。

答案1

造成这种影响的原因之一可能是 systemd 有一个默认设置,如果服务在一定时间间隔内重新启动过于频繁,则会停止服务。这由 StartLimitBurst 和 StartLimitInterval 设置控制。(例如,参见这里这里进行讨论)。对此的指示是这样的

test.service:失败,结果为“start-limit-hit”

如果发生这种情况,您可以在服务状态或 systemd 日志文件中看到此消息

journalctl -b
systemctl status your.service

另一个问题可能是服务单元文件中指令的语法ExecStart=。根据 systemd.service手册页您使用的方式不支持重定向。

具体来说,不支持使用“<”、“<<”、“>”和“>>”进行重定向、使用“|”的管道、使用“&”在后台运行程序以及其他 shell 语法元素。

请注意,shell 命令行不直接受支持。如果要使用 shell 命令行,则需要将其明确传递给某种 shell 实现。

这个修改后的 .service 单元文件在我使用 systemd 237 的 Ubuntu 18.04 桌面上工作正常

[Unit]  
Description=my description  
StartLimitBurst=0  

[Service]  
ExecStart=/bin/sh -c '/bin/date >> /tmp/testtimer.log'  

除了替换 WantedBy=basic.target 之外,我没有更改你的 .timer 单元文件(没有测试与 multi-user.target 相比是否真的有区别)。

这只是一次快速测试,我手动启动了计时器。尚未检查重启时的行为。

编辑
请注意,自 systemd 232 起,已发生更改。最值得注意的是,对于当前的情况,StartLimitIntervalSec(以前称为“StartLimitInterval”)和StartLimitBurst选项现在应放在服务单元文件的 [Unit] 部分中,而不是 [Service] 部分中。

相关内容