文章目录
- systemctl针对timer的配置文件
- systemd.timer的优势
- 任务需求
- sname.timer的设置值
- 使用于OnCalendar的时间
- 一个循环实际运行案例
- 一个固定日期运行的案例
systemctl针对timer的配置文件
有时候,你想要定期执行某些服务或是启动后执行,或是什么服务启动多久后执行等。在过去,我们都是实验crond这个服务来处理,不过,既然现在有一直常驻在内存当中的systemd这个好用的东西,加上systemd有个辅助服务,名为timer.target的家伙,这家伙可以协助定期处理各种任务。那么,除了crond之外,如何使用systemd内置的timer来处理各种任务?
systemd.timer的优势
更加精确的时间控制
:systemd.timer使用机器可读的时间格式,可以更加精确地控制定时任务的触发时间,支持秒级别的时间控制。更加灵活的定时任务控制
:systemd.timer相比于cron等工具,可以执行更加复杂的定时任务控制,如每周特定几天执行任务、每月特定几个工作日执行任务等。支持条件触发
:systemd.timer支持在特定条件下触发定时任务,如特定目录或文件的变化、特定网络事件等。可以管理服务
:systemd.timer可以直接管理服务,即在特定时间触发服务的启动、停止、重启等操作。支持持久化
:systemd.timer可以在系统休眠、重启等情况下持久化定时任务,保证任务不会丢失。更加可靠的日志记录
:systemd.timer使用Journal日志系统,可以更加可靠地记录定时任务的执行情况,支持日志压缩和加密等功能。
虽然还是有些缺点,例如systemd的timer并没有email通知功能(除非自己写一个),也没有类似anacron的一段时间内的随机取样的功能,不过,总体来说还是挺不错的。此外相对于crond最小的单位到分钟,systemd是可以到秒甚至是毫秒。
任务需求
要使用systemd的timer功能,需要满足以下条件:
-
系统中必须启动timer.target,timer.target是systemd中专门用来管理定时器的target,系统默认会启动该target。
-
必须有一个服务存在,该服务以sname.service的形式命名,其中sname为用户自定义的服务名称,该服务用于执行定时任务。
-
必须有一个定时器存在,该定时器以sname.timer的形式命名,其中sname为用户自定义的定时器名称,该定时器用于触发服务的启动、停止等操作。
在满足以上条件的情况下,用户可以通过systemctl命令来管理定时器和服务,如启动、停止、重启定时器和服务等操作。需要注意的是,定时器和服务的配置文件必须放置在systemd的服务配置目录中,通常为/etc/systemd/system/目录。
sname.timer的设置值
Timer部分
设置参数 | 参数意义说明 |
---|---|
OnAcitveSec | 定义定时器首次运行延迟时间,单位为秒。例如,OnActiveSec=5min 表示定时器在服务激活后5分钟后首次运行。 |
OnBootSec | 定义定时器启动时间,相对于系统启动时间的延迟时间,单位为秒。例如,OnBootSec=10min 表示定时器在系统启动后10分钟后运行。 |
OnStartupSec | 用于指定系统启动后,定时器第一次触发的延迟时间。当OnCalendar和OnStartupSec同时存在时,OnStartupSec指定的时间会覆盖OnCalendar中指定的时间。 |
OnUnitActiveSec | 定义定时器启动时间,相对于服务激活时间的延迟时间,单位为秒。例如,OnUnitActiveSec=1h 表示定时器在服务激活后1小时后运行。 |
OnUnitInactiveSec | 定义定时器停止时间,相对于服务停止时间的延迟时间,单位为秒。例如,OnUnitInactiveSec=5min 表示定时器在服务停止后5分钟后停止。 |
OnCalendar | 定义定时器运行的时间表,以机器可读的时间格式表示。例如,OnCalendar=*-*-* 01:00:00 表示定时器在每天凌晨1点触发。 |
Unit | 定义定时器关联的服务名称,即定时器触发后要执行的服务。例如,Unit=mybackup.service 表示定时器关联的服务名称为mybackup.service。 |
Persistent | 定义定时器是否持久化,在系统休眠或重启后是否继续运行定时器。例如,Persistent=true 表示定时器持久化。 |
需要注意的是,以上选项并非全部必须设置,根据实际需求选择设置即可。同时,定时器配置文件必须放置在systemd的服务配置目录中,通常为/etc/systemd/system/目录。
使用于OnCalendar的时间
如果你想要从crontab转成这个timer功能的话,那么要了解时间设置的格式,基本上的格式如下所示:
语法:
英文周名 YYYY-MM-DD HH:MM:SSTHu 2023-5-15 15:34: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等。假设今天是2023-5-13 15:45:00 的话
英文口语 | 实际的时间格式代表 |
---|---|
now | Thu 2023-5-13 15:45:00 |
today | Thu 2023-5-13 00:00:00 |
tomorrow | Thu 2023-5-14 00:00:00 |
hourly | *-*-* *:00:00 |
daily | *-*-* 00:00:00 |
weekly | Mon *-*-* 00:00:00 |
monthly | *-*-01 00:00:00 |
+3h10m | Thu 2023-5-13 18:45:00 |
2023-5-20 | Sun 2023-5-20 00:00:00 |
一个循环实际运行案例
https://blog.csdn.net/qq_52089863/article/details/130675679?spm=1001.2014.3001.5502
如上链接就是之前章节自己做的系统备份服务,我们能不能让这个服务定期执行?
假设这样:
- 启动后2小时开始执行一次这个backup.service
- 自从第一次执行后,未来我每两天要执行一次backup.serivce
那么应该如何处理这个脚本呢?
[root@localhost ~]# vim /etc/systemd/system/backup.timer
[Unit]
Description=backup my server timer
[Timer]
OnBootSec=2h
OnUnitActiveSec=2days
[Install]
WantedBy=multi-user.target
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl restart backup.timer
[root@localhost ~]# systemctl enable backup.timer
Created symlink from /etc/systemd/system/multi-user.target.wants/backup.timer to /etc/systemd/system/backup.timer.
[root@localhost ~]# systemctl list-unit-files | grep backup
backup.service static # 这个不需要启动,只要enable backup.service 即可
backup.timer enabled
[root@localhost ~]# systemctl show timers.target
ConditionTimestamp=一 2023-05-15 14:40:04 CST # timer这个unit启动的时间
[root@localhost ~]# systemctl show backup.service
ExecMainExitTimestamp=一 2023-05-15 16:13:49 CST # backup.service 上次执行时间
[root@localhost ~]# systemctl show backup.timer |grep Nex
NextElapseUSecMonotonic=2d 1h 33min 49.172309s # 下一次距离 timer.target 的时间
代码解释:
- 编辑backup.timer文件,指定定时器的触发时间和重复周期。OnBootSec=2h指定了在系统启动后2小时后第一次执行备份任务,OnUnitActiveSec=2days指定了备份任务的重复周期,即每2天执行一次备份。
- 使用systemctl daemon-reload命令重新加载systemd守护进程,以便读取新的定时器配置。
- 使用systemctl restart backup.timer命令重启backup.timer定时器,以便应用新的定时器配置。
- 使用systemctl enable backup.timer命令启用backup.timer定时器,以便在系统启动时自动启动该定时器。
- 使用systemctl list-unit-files | grep backup命令检查备份服务和定时器的状态。该命令显示backup.service服务已启用,backup.timer定时器已启用且已创建符号链接以确保在系统启动时自动启动该定时器。
- 使用systemctl show timers.target命令查看timers.target的状态,其中ConditionTimestamp选项显示定时器最近一次启动的时间,即2023年5月15日14:40:04。
- 使用systemctl show backup.service命令查看备份服务的状态,其中ExecMainExitTimestamp选项显示上次备份任务执行的时间,即2023年5月15日16:13:49。
- 使用systemctl show backup.timer |grep Nex命令查看下一次备份任务执行的时间,其中NextElapseUSecMonotonic选项显示距离下一次备份任务执行的时间,即2天1小时33分钟49.172309秒。
一个固定日期运行的案例
那如果我希望不管上面如何运行,我都希望星期天凌晨2点运行这个备份程序一遍该怎么做?因为已经存在了backup.timer。所以,这里用backup2.timer来做区别
[root@localhost ~]# 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@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl restart backup2.timer
[root@localhost ~]# systemctl start backup2.timer
[root@localhost ~]# systmectl show backup2.timer
NextElapseUSecRealtime=53y 4month 2w 3d 18h
与循环时间运行差异比较大的地方,在于这个OnCalendar的方法对照的时间并不是times.target的启动时间,而是UNIX标准时间,也就是与1970-01-01 00:00:00 这个时间比较。因此,当你看到最后出现的NextElapseUSecRealtime时,下一次执行还要53年4个月2周3天18时,为什么会这样呢?因为对比的是【日历时间】而不是某个unit的启动时间。
代码解释
- 编辑backup2.timer文件,指定定时器的触发时间和重复周期。OnCalendar选项指定了定时器在每个星期日的凌晨2点执行备份任务。
- 在[Timer]区块中增加Persistent=true选项,以便使定时器在系统重启后继续运行。
- 在[Timer]区块中增加Unit选项,指定定时器触发后需要执行的服务,即backup.service。
- 使用systemctl daemon-reload命令重新加载systemd守护进程,以便读取新的定时器配置。
- 使用systemctl restart backup2.timer命令重启backup2.timer定时器,以便应用新的定时器配置。
- 使用systemctl start backup2.timer命令启动backup2.timer定时器,以便立即启动该定时器。
- 使用systemctl show backup2.timer命令查看backup2.timer定时器的状态,其中NextElapseUSecRealtime选项显示下一次备份任务执行的时间,即距离现在53年4个月2周3天18小时。这是由于OnCalendar选项指定了备份任务在每个星期日的凌晨2点执行,而当前时间可能不是星期日凌晨2点,因此下一次备份任务执行的时间距离当前时间比较长。
通过这样的方式,你就可以使用systemd的timer来制作属于你的计划任务了。