![为什么 Systemd.timer 会在 OnCalendar 上暂停一段时间](https://linux22.com/image/1598811/%E4%B8%BA%E4%BB%80%E4%B9%88%20Systemd.timer%20%E4%BC%9A%E5%9C%A8%20OnCalendar%20%E4%B8%8A%E6%9A%82%E5%81%9C%E4%B8%80%E6%AE%B5%E6%97%B6%E9%97%B4.png)
我使用 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] 部分中。