Use Systemd Timers Instead of Cron Jobs

某次逛论坛,发现使用Systemd管理的Linux发行版,应该使用Systemd Timers管理定时任务,并替代原来的Cron Jobs。

1. Systemd Units

Systemd Units(单元),是System的最小功能单位。其按功能划分为12种类型,例如target、service、timer等。“单元”之间互相依赖和调用,组成Systemd这个任务管理系统。

System Units存放路径:

  • /usr/lib/systemd/system,系统默认的单元文件
  • /etc/systemd/system,用户安装的软件的单元文件

注意:

  • Debian 12中,/usr/lib映射到/lib,所以/lib/systemd/system/usr/lib/systemd/system的文件相同。
  • Systemd读取Unit文件时,先读/usr/lib/systemd/system,再读/etc/systemd/system。所以修改原来的Unit文件,或者自定义的Unit文件,建议放在/etc/systemd/system
  • 编辑Unit文件,建议使用命令systemctl edit --full xxx.service,保存后会自动reload。

配置Systemd定时器时,需要创建两个Unit:

  • xxx.service,service类型,用于配置需要执行的任务。如果该任务已配置,则不用创建此文件。
  • xxx.timer,timer类型,对xxx.service执行定时操作。

2. 创建Systemd Service

对于Cron Job,会把定时执行的脚本或命令,与定时配置写在一起。配置是简单直接,但是不好管理。Systemd需要把定时执行的任务,配置为oneshot的Service。

例如创建文件/etc/systemd/system/sample-job.service

[Unit]
Description=sample job
Requires=network-online.target

[Service]
Type=oneshot
ExecStart=/bin/bash /path/to/sample-job.sh

[Install]
WantedBy=multi-user.target

注意:

  • Type=oneshot,表示只运行一次,不用长期运行。
  • Requires,配置了需要网络服务联网成功,才能执行。
  • WantedBy,配置了多用户命令状态时,才能执行。

3. 创建Systemd Timer

例如创建文件/etc/systemd/system/sample-job.timer

[Unit]
Description=Auto run sample job
Requires=sample-job.service

[Timer]
OnCalendar=Mon,Thu *-*-* 01:23:49
Unit=sample-job.service

[Install]
WantedBy=multi-user.target

注意:

  • Unit,配置对应的Service。
  • Requires,需要依赖的Service,可不配。
  • OnCalendar,按配置的日期时间进行定时运行。格式是DOW yyyy-MM-dd HH:mm:ss,其中DOW可以是Mon,Fri(周一和周五这2天)或者Mon..Fri(周一到周五这5天)
    • 详细参考:https://www.freedesktop.org/software/systemd/man/latest/systemd.time.html#Calendar%20Events

4. 管理

# 启动定时器
sudo systemctl start sample-job.timer
# 停止定时器
sudo systemctl stop sample-job.timer
# 查看定时器状态
systemctl status sample-job.timer
# 列出正在运行的定时器
systemctl list-timers
# 设置开机启动
sudo systemctl enable sample-job.timer
# 取消开启启动
sudo systemctl disable sample-job.timer

参考

使用 Hugo 构建
主题 StackJimmy 设计