timer Unit
概述
参考:
所有以 .timer
结尾的 Unit 都是由 Systemd 控制和监督的定时器任务。这是一个替代 Linux 中的 Crontab 程序的功能。通过 timer 单元,可以通过 systemd 来管理所有定时任务。
timer 指令
阮一峰文章
一、定时任务
所谓定时任务,就是未来的某个或多个时点,预定要执行的任务,比如每五分钟收一次邮件、每天半夜两点分析一下日志等等。
Linux 系统通常都使用 cron 设置定时任务,但是 Systemd 也有这个功能,而且优点显著。
- 自动生成日志,配合 Systemd 的日志工具,很方便除错
- 可以设置内存和 CPU 的使用额度,比如最多使用 50% 的 CPU
- 任务可以拆分,依赖其他 Systemd 单元,完成非常复杂的任务
下面,我就来演示一个 Systemd 定时任务:每小时发送一封电子邮件。
二、邮件脚本
先写一个发邮件的脚本mail.sh
。
echo "This is the body" | /usr/bin/mail -s "Subject" [someone@example](mailto:someone@example).com
上面代码的someone@example.com
,请替换成你的邮箱地址。
然后,执行这个脚本。
bash mail.sh
执行后,你应该就会收到一封邮件,标题为Subject
。
如果你的 Linux 系统不能发邮件,建议安装 ssmtp 或者 msmtp。另外,mail
命令的用法,可以参考这里。
三、Systemd 单元
学习 Systemd 的第一步,就是搞懂 “单元”(unit)是什么。
简单说,单元就是 Systemd 的最小功能单位,是单个进程的描述。一个个小的单元互相调用和依赖,组成一个庞大的任务管理系统,这就是 Systemd 的基本思想。
由于 Systemd 要做的事情太多,导致单元有很多不同的种类,大概一共有 12 种。举例来说,Service 单元负责后台服务,Timer 单元负责定时器,Slice 单元负责资源的分配。
每个单元都有一个单元描述文件,它们分散在三个目录。
/lib/systemd/system
:系统默认的单元文件/etc/systemd/system
:用户安装的软件的单元文件/usr/lib/systemd/system
:用户自己定义的单元文件
下面的命令可以查看所有的单元文件。
systemctl list-unit-files
systemctl list-unit-files --type service
systemctl list-unit-files --type timer
四、单元的管理命令
下面是常用的单元管理命令。
systemctl start [UnitName]
systemctl stop [UnitName]
systemctl restart [UnitName]
systemctl kill [UnitName]
systemctl status [UnitName]
systemctl enable [UnitName]
systemctl disable [UnitName]
五、Service 单元
前面说过,Service 单元就是所要执行的任务,比如发送邮件就是一种 Service。
新建 Service 非常简单,就是在/usr/lib/systemd/system
目录里面新建一个文件,比如mytimer.service
文件,你可以写入下面的内容。
[Unit]
Description=MyTimer
[Service]
ExecStart=/bin/bash /path/to/mail.sh
可以看到,这个 Service 单元文件分成两个部分。
[Unit]
部分介绍本单元的基本信息(即元数据),Description
字段给出这个单元的简单介绍(名字叫做MyTimer
)。
[Service]
部分用来定制行为,Systemd 提供许多字段。
ExecStart
:systemctl start
所要执行的命令ExecStop
:systemctl stop
所要执行的命令ExecReload
:systemctl reload
所要执行的命令ExecStartPre
:ExecStart
之前自动执行的命令ExecStartPost
:ExecStart
之后自动执行的命令ExecStopPost
:ExecStop
之后自动执行的命令
注意,定义的时候,所有路径都要写成绝对路径,比如bash
要写成/bin/bash
,否则 Systemd 会找不到。
现在,启动这个 Service。
sudo systemctl start mytimer.service
如果一切正常,你应该就会收到一封邮件。
六、Timer 单元
Service 单元只是定义了如何执行任务,要定时执行这个 Service,还必须定义 Timer 单元。
/usr/lib/systemd/system
目录里面,新建一个mytimer.timer
文件,写入下面的内容。
[Unit]
Description=Runs mytimer every hour
[Timer]
OnUnitActiveSec=1h
Unit=mytimer.service
[Install]
WantedBy=multi-user.target
这个 Timer 单元文件分成几个部分。
[Unit]
部分定义元数据。
[Timer]
部分定制定时器。Systemd 提供以下一些字段。
OnActiveSec
:定时器生效后,多少时间开始执行任务OnBootSec
:系统启动后,多少时间开始执行任务OnStartupSec
:Systemd 进程启动后,多少时间开始执行任务OnUnitActiveSec
:该单元上次执行后,等多少时间再次执行OnUnitInactiveSec
: 定时器上次关闭后多少时间,再次执行OnCalendar
:基于绝对时间,而不是相对时间执行AccuracySec
:如果因为各种原因,任务必须推迟执行,推迟的最大秒数,默认是 60 秒Unit
:真正要执行的任务,默认是同名的带有.service
后缀的单元Persistent
:如果设置了该字段,即使定时器到时没有启动,也会自动执行相应的单元WakeSystem
:如果系统休眠,是否自动唤醒系统
上面的脚本里面,OnUnitActiveSec=1h
表示一小时执行一次任务。其他的写法还有OnUnitActiveSec=*-*-* 02:00:00
表示每天凌晨两点执行,OnUnitActiveSec=Mon *-*-* 02:00:00
表示每周一凌晨两点执行,具体请参考官方文档。
七、[Install] 和 target
mytimer.timer
文件里面,还有一个[Install]
部分,定义开机自启动(systemctl enable
)和关闭开机自启动(systemctl disable
)这个单元时,所要执行的命令。
上面脚本中,[Install]
部分只写了一个字段,即WantedBy=multi-user.target
。它的意思是,如果执行了systemctl enable mytimer.timer
(只要开机,定时器自动生效),那么该定时器归属于multi-user.target
。
所谓 Target 指的是一组相关进程,有点像 init 进程模式下面的启动级别。启动某个 Target 的时候,属于这个 Target 的所有进程都会全部启动。
multi-user.target
是一个最常用的 Target,意为多用户模式。也就是说,当系统以多用户模式启动时,就会一起启动mytimer.timer
。它背后的操作其实很简单,执行systemctl enable mytimer.timer
命令时,就会在multi-user.target.wants
目录里面创建一个符号链接,指向mytimer.timer
。
八、定时器的相关命令
下面,启动刚刚新建的这个定时器。
sudo systemctl start mytimer.timer
你应该立刻就会收到邮件,然后每个小时都会收到同样邮件。
查看这个定时器的状态。
systemctl status mytimer.timer
查看所有正在运行的定时器。
systemctl list-timers
关闭这个定时器。
sudo systemctl stop myscript.timer
下次开机,自动运行这个定时器。
sudo systemctl enable myscript.timer
关闭定时器的开机自启动。
sudo systemctl disable myscript.timer
九、日志相关命令
如果发生问题,就需要查看日志。Systemd 的日志功能很强,提供统一的命令。
sudo journalctl
sudo journalctl -u mytimer.timer
sudo journalctl -u mytimer
sudo journalctl -f
journalctl -f -u timer.timer
十、参考链接
- How to Use Systemd Timers, by Jason Graham
- Using systemd as a better cron, by luqmaan
- Getting started with systemd, by CoreOS
- systemd/Timers, by ArchWiki
- Understanding Systemd Units and Unit Files, by Justin Ellingwood
(完)
反馈
此页是否对你有帮助?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.