Linux | systemd - 时间和定时器
上一篇我们随便说了说systemd的基础的一些东西,组件啊、类型啊服务啊什么的。这篇稍微提一下systemd中的时间和定时器。
计算机中的时间
计算机是一个讲究时间的玩意儿,几乎任何程序都会涉及到什么时候去做什么,会有时刻的问题,也会有时长的问题。
要搞清楚定时任务怎么回事,我们得先搞清楚时间的问题。
挂钟计时器
挂钟计时器指的是一个本地的时间,这个时间会因为网络时间服务的调整而作细微的调整,也会因为时区变化甚至标准时钟时间的调整而变化。并不是连续增长的。一般按照日历来计算的时间都是挂钟计时器。
单调计时器
单调计时器就是我们自然中持续增长的时间。比如说我们说每天要吃饭,我们不会因为横穿时区而不吃饭,这个每天就是一个单调计时器。这种一般都是单调计时器。
定时器
systemd除了正常的资源以外,还定义了一类资源叫timer。会根据需求定时触发,可以单次可以循环。可以替代cron和at。
timer类似于service,都是systemd unit,所以Unit和Install这两段timer同样可以用。
基本的定时器: 根据挂钟计时器定时启动unit
timer最简单的用法和cron类似,就是定义一个时刻,systemd会在这个时刻启用某个资源。
举个例子,我们可以让systemd在某一个或者某一些时刻启动服务。我们的服务就是打印Happy Birthday
[Service]
ExecStart=/usr/bin/echo Happy Birthday
如果我们要在每年我的生日之时打印这个,就需要一个Timer:
[Timer]
OnCalandar=*-6-15 00:00:00 CST
如果只是要运行一次,那我们写一个具体的时间就行:
[Timer]
OnCalandar=1995-6-15 00:00:00 CST
不过这样的话,systemd不会和你说Happy Birthday。
错过了?没事,补上。
有的时候机器维护,或者出现了故障,定时任务需要在恢复后马上跑一次。怎么办呢?
有一个Persistent选项:
[Timer]
OnCalandar=*-6-15 00:00:00 CST
即使2020年6月15号机器关机,16号启动的时候,systemd还是会告诉你: Happy Birthday。
我不要按照日历
ok,没问题。timer也可以根据下面这些条件周期性启动(不带单位都是秒):
- OnActiveSec: 相对于timer启动的时间
- OnBootSec: 相对于计算机启动的时间
- OnStartupSec: 相对于服务管理器启动的时间
- OnUnitActiveSec: 相对于上次unit启动的时间
- OnUnitInactiveSec: 相对于上次unit停止的时间
比如说
[Timer]
OnBootSec=300
OnUnitActiveSec=1w
机器启动后五分钟启动一次,然后每周启动一次。
我不想让它扎堆
有的时候服务开机扎堆跑,导致负载比较高。我想让时间随机一点。
没问题。
[Timer]
RandomizedDelaySec=10
OnCalandar=1995-6-15 00:00:00 CST
会在设置的时间前后,随机加不超过10s的一段时间。
我想临时新建并启动一个timer,在关机前有效
systemd提供了一个命令叫systemd-run,来提供生成并启动一个timer、关机前有效的能力。
比如说:
systemd-run --on-calendar='*-6-15 00:00:00 CST' echo Happy Birthday
这里有一个略微有趣的用法就是,通过systemd-run来替代at
systemd-run --on-active=30 /bin/echo Welcome!