Ale*_*lke 6 cron timer systemd
我有一个悲伤的印象,计时器的滴答声正在滑动AccuracySec。
我习惯了 CRON,并且使用诸如“*/5 * * * ...”之类的东西,它会每 5 分钟运行一次(尽管如果仍在运行,它不会重新启动进程,这正是我所需要的。)
CRON 时间表可以定义为:
...--|-----|-----|--...--->
:05 :10 :15
Run Code Online (Sandbox Code Playgroud)
现在我将其转换为systemd如下所示的文件:
[Unit]
Description=Run the snapbackend service once every 5 minutes.
[Timer]
OnUnitActiveSec=5min
[Install]
WantedBy=timers.target
Run Code Online (Sandbox Code Playgroud)
所以我还是想每 5 分钟打一次勾。
但是,他们指定了此参数AccuracySec,并且默认设置为 1 分钟。正如你所看到的,我没有设置它,因为它说:
这样做是为了优化功耗以抑制不必要的 CPU 唤醒。
但看起来他们将计时器同步在一起,而不是按时开始新任务。不仅如此,它的实施方式似乎AccuracySec是累积的。看起来是这样的:
...--|-----+-|-----+-|-----+-|--...
:05 :11 :17 :23
Run Code Online (Sandbox Code Playgroud)
表示+定时器超时的时间, 表示|定时服务执行的时间。
在我看来,1 分钟的延迟意味着下一个计时器将“迟到”2 分钟,而不是仅延迟 1 分钟。如我的时间表所示,对于systemd计时器,滴答发生在:05、:11、:17、:23。我期待的是: :05、:10、:15、:20 等...(请注意,如果第一个滴答声在 :05 命中,则计时器计划为 :04 并等待 1 分钟而不醒来CPU 太快了。然后它会在 :09 处计算下一个时钟周期,但仅在 :10 处执行,依此类推)
计时器正在滑动,我说得对吗?
快速回答:是的。它滑倒了。(注意:这是在 Ubuntu 16.04 中,也许它会在更高版本的 systemd 中得到修复......)
正如@MarkStosberg在他的回答中提出的,我创建了一个没有Accuracy变量的计时器,以便使用默认的1分钟,然后添加变量来测试1秒,看看我的时间是否会滑动。
快照测试定时器
snaptest.timer首先,我创建了一个不带参数命名的文件AccuracySec:
[Unit]
Description=Test the slipping timer...
[Timer]
OnUnitActiveSec=5min
[Install]
WantedBy=timers.target
Run Code Online (Sandbox Code Playgroud)
对于第二次测试,我添加了该AccuracySec参数并将其设置为 1(表示 1 秒):
[Unit]
Description=Test the slipping timer...
[Timer]
OnUnitActiveSec=5min
AccuracySec=1 <-- added this for 2nd test
[Install]
WantedBy=timers.target
Run Code Online (Sandbox Code Playgroud)
快照测试服务
其次,我创建了一个名为snaptest.service:
[Unit]
Description=Test slippage by logging messages
[Service]
Type=simple
ExecStart=/usr/bin/snaptest
[Install]
WantedBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)
/usr/bin/snaptest
第三,我创建了一个名为/usr/bin/snaptest:
#!/bin/sh
echo `date` >>/var/log/snapwebsites/snaptest.log
Run Code Online (Sandbox Code Playgroud)
一个非常简单的脚本确实给了我一个名为snaptest.log.
对于那些不知道的人,要启动计时器,您只需执行以下操作即可:
systemctl start snaptest.timer
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您必须指定“.timer”。
此外,这还不够,因为除非snaptest.service服务至少运行一次,否则计时器不会启动。所以第一次运行需要踢:
systemctl start snaptest
Run Code Online (Sandbox Code Playgroud)
第一组显示结果,默认精度为 1 分钟:
Mon Aug 29 14:34:07 PDT 2016
Mon Aug 29 14:39:09 PDT 2016
Mon Aug 29 14:44:37 PDT 2016
Mon Aug 29 14:50:09 PDT 2016
Mon Aug 29 14:56:09 PDT 2016
Mon Aug 29 15:02:09 PDT 2016
Mon Aug 29 15:08:09 PDT 2016
Mon Aug 29 15:14:09 PDT 2016
Mon Aug 29 15:20:09 PDT 2016
Mon Aug 29 15:26:09 PDT 2016
Mon Aug 29 15:32:09 PDT 2016
Mon Aug 29 15:38:09 PDT 2016
Mon Aug 29 15:44:09 PDT 2016
Mon Aug 29 15:50:09 PDT 2016
Mon Aug 29 15:56:09 PDT 2016
Mon Aug 29 16:02:09 PDT 2016
Mon Aug 29 16:08:09 PDT 2016
Mon Aug 29 16:14:09 PDT 2016
Mon Aug 29 16:20:09 PDT 2016
Mon Aug 29 16:26:09 PDT 2016
Mon Aug 29 16:32:09 PDT 2016
Mon Aug 29 16:38:09 PDT 2016
Mon Aug 29 16:44:09 PDT 2016
Mon Aug 29 16:50:09 PDT 2016
Mon Aug 29 16:56:09 PDT 2016
Mon Aug 29 17:02:09 PDT 2016
Mon Aug 29 17:08:09 PDT 2016
Mon Aug 29 17:14:09 PDT 2016
Run Code Online (Sandbox Code Playgroud)
第二组结果显示结果,精度为1秒:
Mon Aug 29 17:19:57 PDT 2016
Mon Aug 29 17:24:57 PDT 2016
Mon Aug 29 17:29:58 PDT 2016
Mon Aug 29 17:34:59 PDT 2016
Mon Aug 29 17:40:00 PDT 2016
Mon Aug 29 17:45:01 PDT 2016
Mon Aug 29 17:50:02 PDT 2016
Mon Aug 29 17:55:03 PDT 2016
Mon Aug 29 18:00:04 PDT 2016
Mon Aug 29 18:05:05 PDT 2016
Mon Aug 29 18:10:06 PDT 2016
Mon Aug 29 18:15:07 PDT 2016
Mon Aug 29 18:20:08 PDT 2016
Mon Aug 29 18:25:09 PDT 2016
Mon Aug 29 18:30:10 PDT 2016
Mon Aug 29 18:35:11 PDT 2016
Mon Aug 29 18:40:12 PDT 2016
Mon Aug 29 18:45:13 PDT 2016
Mon Aug 29 18:50:14 PDT 2016
Mon Aug 29 18:55:15 PDT 2016
Mon Aug 29 19:00:16 PDT 2016
Mon Aug 29 19:05:17 PDT 2016
Mon Aug 29 19:10:18 PDT 2016
Mon Aug 29 19:15:19 PDT 2016
Mon Aug 29 19:20:20 PDT 2016
Mon Aug 29 19:25:21 PDT 2016
Mon Aug 29 19:30:22 PDT 2016
Mon Aug 29 19:35:23 PDT 2016
Mon Aug 29 19:40:24 PDT 2016
Mon Aug 29 19:45:25 PDT 2016
Mon Aug 29 19:50:26 PDT 2016
Mon Aug 29 19:55:27 PDT 2016
Mon Aug 29 20:00:28 PDT 2016
Mon Aug 29 20:05:29 PDT 2016
Mon Aug 29 20:10:30 PDT 2016
Mon Aug 29 20:15:31 PDT 2016
Run Code Online (Sandbox Code Playgroud)
显然,它会滑动......通过在 0 和 之间变化的时间窗口AccuracySec。
我想如果我想避免滑点,我必须使用该OnCalendar选项。
根据systemd.timers 的文档,计时器没有滑动。计时器“每 5 分钟运行一次”,但每 5 分钟窗口内的执行时间是随机的。当您不希望在特定时间间隔内出现“蜂拥而至”的活动,但又希望平衡后台服务的负载时,这通常是集群中理想的行为。
正如文档所说,
为了获得最佳精度,请将 [AccuracySecs] 设置为 1us 。
您可以通过创建一个虚拟服务来进行检查,该服务仅每 5 分钟写入日志文件或日志,然后让它运行半小时。尝试使用和不使用AccuracySecs=1us。
我预计两次运行都会每 5 分钟产生一次运行,并且AccuracySecs=1us每 5 分钟恰好产生一次运行。