linux systemd timer unit的配置


systemctl 针对 timer 的配置文件

回到顶部
有时候,某些服务你想要定期执行,或者是开机后执行,或者是什么服务启动多久后执行等等的。在 过去,我们大概都是使用 crond 这个服务来定期处理, 不过,既然现在有一直常驻在内存当中的 systemd 这个好用的东西,加上这 systemd 有个协力服务,名为 timers.target 的家伙,这家伙可以协助定期处理各种任务! 那么, 除了 crond 之外,如何使用 systemd 内建的 time 来处理各种任务呢?
这就是本小节的重点啰!

systemd.timer 的优势

回到顶部
在 archlinux 的官网 wiki 上面有提到,为啥要使用 systemd.timer 呢? 由于所有的 systemd 的服务产生的信息都会被纪录 (log),因此比 crond 在 debug 上面要更清楚方便的多;
各项 timer 的工作可以跟 systemd 的服务相结合;
各项 timer 的工作可以跟 control group (cgroup,用来取代 /etc/secure/limit.conf 的功能) 结合,来限制该工 作的资源利用 虽然还是有些弱点啦~例如 systemd 的 timer 并没有 email 通知的功能 (除非自己写一个),也没有 类似 anacron 的一段时间内的随机取样功能 (random_delay), 不过,总体来说,还是挺不错的!此 外,相对于 crond 最小的单位到分, systemd 是可以到秒甚至是毫秒的单位哩!相当有趣!
任务需求
基本上,想要使用 systemd 的 timer 功能,你必须要有几个要件:
系统的 timer.target 一定要启动
要有个 sname.service 的服务存在 (sname 是你自己指定的名称)
要有个 sname.timer 的时间启动服务存在
满足上面的需求就 OK 了!有没有什么案例可以来实作看看?这样说好了,我们上个小节不是才自 己做了个 backup.service 的服务吗?那么能不能将这个 backup.service 用在定期执行上面呢?好啊!
那就来测试看看!
sname.timer 的设置值
你可以到 /etc/systemd/system 底下去建立这个 *.timer 档,那这个文件的内容要项有哪些东西呢? 基本设置主要有底下这些: (man systemd.timer & man systemd.time)
[Timer] 部份设置参数 参数意义说明
OnActiveSec 当 timers.target 启动多久之后才执行这只unit
OnBootSec 当开机完成后多久之后才执行
OnStartupSec 当 systemd 第一次启动之后过多久才执行
OnUnitActiveSec 这个 timer 配置文件所管理的那个 unit 服务在最后一次启动后,隔多久后再执行一次的意思
OnUnitInactiveSec 这个 timer 配置文件所管理的那个 unit 服务在最后一次停止后,隔多久再执行一次的意思。
OnCalendar 使用实际时间 (非循环时间) 的方式来启动服务的意思!至于时间的格式后续再来谈。
Unit 一般 来说不太 需要设置,因 此如同上 面刚刚提到的 ,基本上 我们设置都是 sname.service + sname.timer,那如果你的 sname 并不相同时, 那在 .timer 的文件中, 就得要指定是哪一个service unit 啰!
Persistent 当使用 OnCalendar 的设置时,指定该功能要不要持续进行的意思。通常是设置为 yes ,比较能够满足类似 anacron 的功能喔!
基本的项目仅有这些而已,在设置上其实并不困难啦!
使用于 OnCalendar 的时间
如果你想要从 crontab 转成这个 timer 功能的话,那么对于时间设置的格式就得要了解了解~基本上的格式如下所示:
语法:英文周名 YYYY-MM-DD HH:MM:SS
范例:Thu 2015-08-13 13:40:00
上面谈的是基本的语法,你也可以直接使用间隔时间来处理!常用的间隔时间单位有:
us 或 usec:微秒 (10 -6 秒)
ms 或 msec:毫秒 (10 -3 秒)
s, sec, second, seconds
m, min, minute, minutes
h, hr, hour, hours
d, day, days
w, week, weeks
month, months
y, year, years
常见的使用范例有:
隔 3 小时: 3h 或 3hr 或 3hours
隔 300 分钟过 10 秒: 10s 300m
隔 5 天又 100 分钟: 100m 5day
# 通常英文的写法,小单位写前面,大单位写后面~所以先秒、再分、再小时、再天数等~ 此外,你也可以使用英文常用的口语化日期代表,例如 today, tomorrow 等!假设今天是 2015-08-13 13:50:00 的话,那么:
英文口语 实际的时间格式代表
now Thu 2015-08-13 13:50:00
today Thu 2015-08-13 00:00:00
tomorrow Thu 2015-08-14 00:00:00
hourly *-*-* *:00:00
daily *-*-* 00:00:00
weekly Mon *-*-* 00:00:00
monthly *-*-01 00:00:00
+3h10m Thu 2015-08-13 17:00:00
2015-08-16 Sun 2015-08-16 00:00:00
一个循环时间运作的案例
现在假设这样:
开机后 2 小时开始执行一次这个 backup.service
自从第一次执行后,未来我每两天要执行一次 backup.service
好了,那么应该如何处理这个脚本呢?可以这样做喔!
[root@initroot ~]# vim /etc/systemd/system/backup.timer
[Unit]
Description=backup my server timer
[Timer]
OnBootSec=2hrs
OnUnitActiveSec=2days
[Install]
WantedBy=multi-user.target
# 只要这样设置就够了!储存离开吧!
[root@initroot ~]# systemctl daemon-reload
[root@initroot ~]# systemctl enable backup.timer
[root@initroot ~]# systemctl restart backup.timer
[root@initroot ~]# systemctl list-unit-files | grep backup
backup.service disabled
backup.timer enabled
# 这个不需要启动!只要 enable backup.timer 即可!
[root@initroot ~]# systemctl show timers.targetConditionTimestamp=Thu 2015-08-13 14:31:11 CST
# timer 这个 unit 启动的时间!
[root@initroot ~]# systemctl show backup.service
ExecMainExitTimestamp=Thu 2015-08-13 14:50:19 CST
# backup.service 上次执行的时间
[root@initroot ~]# systemctl show backup.timer
NextElapseUSecMonotonic=2d 19min 11.540653s
# 下一次执行距离 timers.target 的时间 如上表所示,我上次执行 backup.service 的时间是在 2015-08-13 14:50 ,由于设置两个小时执行一 次,因此下次应该是 2015-08-15 14:50 执行才对! 由于 timer 是由 timers.target 这个 unit 所管理 的,而这个 timers.target 的启动时间是在 2015-08-13 14:31 , 要注意,最终 backup.timer 所纪录的 下次运行时间,其实是与 timers.target 所纪录的时间差!因此是 2015-08-15 14:50 - 2015-08-13 14:31 才对! 所以时间差就是 2d 19min 啰!
一个固定日期运作的案例
上面的案例是固定周期运作一次,那如果我希望不管上面如何运作了,我都希望星期天凌晨 2 点运 作这个备份程序一遍呢?请注意,因为已经存在 backup.timer 了! 所以,这里我用 backup2.timer 来 做区隔喔!
[root@initroot ~]# vim /etc/systemd/system/backup2.timer
[Unit]
Description=backup my server timer2
[Timer]
OnCalendar=Sun *-*-* 02:00:00
Persistent=true
Unit=backup.service
[Install]
WantedBy=multi-user.target
[root@initroot ~]# systemctl daemon-reload
[root@initroot ~]# systemctl enable backup2.timer
[root@initroot ~]# systemctl start backup2.timer
[root@initroot ~]# systemctl show backup2.timer
NextElapseUSecRealtime=45y 7month 1w 6d 10h 30min
与循环时间运作差异比较大的地方,在于这个 OnCalendar 的方法对照的时间并不是 times.target 的启动时间,而是 Unix 标准时间!
亦即是 1970-01-01 00:00:00 去比较的!因此,当你看到最后出现的 NextElapseUSecRealtime 时,哇!
下一次执行还要 45 年 + 7 个月 + 1 周 + 6 天 + 10 小时过30 分~刚看到的时候,确实因此揉了揉眼睛~确定没有看错...这才了解原来比对的是日历时间而不是某个 unit 的启动时间啊!
呵呵!通过这样的方式,你就可以使用 systemd 的 timer 来制作属于你的时程规划服务啰!

initroot编辑整理,转载请注明www.initroot.com

100次点赞 100次阅读