哪种方法更有效:使用循环运行脚本还是让 systemd 使用计时器执行脚本?

哪种方法更有效:使用循环运行脚本还是让 systemd 使用计时器执行脚本?

我想让 (bash) 脚本每秒在后台执行一次或两次。我看到两种可能的解决方案:

  1. 在脚本中包含一个循环(使用 sleep 命令)并执行一次脚本。
  2. 不包含循环并通过 systemd 计时器重复执行脚本。

我的问题是:

  • 这些方法可能有哪些缺点和优点?
  • 还有更好的选择吗?

答案1

“每秒一次或两次”已经足够频繁了,所以我会选择循环选项,但让我们来看看其中的一些区别。

  • 带有循环的脚本即使不执行任何操作也会消耗少量资源(占用一个 PID、将代码加载到内存中 [尽管可能被换出] 等)。systemd 计时器的成本较低,我认为基本上是一个 timerfd。

    • 对于 shell 脚本(与 Python 脚本相反),您还需要为sleep始终启动新进程付出一点代价。(除非sleep是 shell 中的内置命令,但在 Bash 中不是。)
  • 计时器每次启动程序都会产生成本。此成本因程序而异(例如,对于 Java 程序,成本会很大,每次程序结束时都会丢弃优化结果;对于 shell 脚本,成本可能没那么严重)。

  • 计时器将导致其相应的服务在每次启动和停止时记录到日志中。(对我来说,这是在您的场景中不选择计时器的主要原因。每秒几条消息是大量的日志垃圾邮件。)

  • 每次计时器到期时启动一个新的服务实例,可以为每个实例提供单独的资源核算(请参阅systemd.资源控制(5))。例如,如果出于某种原因,您的服务在凌晨消耗了更多的磁盘 I/O,这将记录在日志中以供日后分析,假设您启用了记账功能(它是日志消息的一部分:“消耗XCPU 时间,读取从磁盘”等)。

  • systemd 定时器默认的精度只有一分钟,以便允许同时启动多个定时器,从而减少 CPU 唤醒。这可以更改(例如AccuracySec=1us,请参阅systemd.定时器(5)),但这可能表明按每秒触发计时器超出了最典型的用例。

  • 使用 systemd 计时器,您可以方便地查看上次运行的时间以及下次运行的时间systemctl list-timers。自制的睡眠循环可能无法提供相同级别的洞察力。

  • 使用计时器时,对服务的更改将在下次计时器触发时生效。如果服务有自己的循环,则需要重新启动才能使更改生效。

我不知道其他替代方案。老牌的 cron(无论你使用哪种实现)可能具有与 systemd 计时器相同的一些优点(例如较低的休眠成本),以及相同的一些缺点(例如较高的启动成本)。

相关内容