systemd 定时器实战:用 Timer Unit 取代 Cron 的现代任务编排 原创

温馨提示:
本文最后更新于 2026-11-03,已超过 1 天没有更新。 若文章内的图片失效(无法正常加载),请留言反馈或直接 联系我。

为什么用 systemd 定时器取代 Cron

在传统 Linux 服务器上,周期性任务通常交给 Cron(crontab)处理。但 Cron 存在几个先天短板:任务输出默认丢失、依赖单独的守护进程、无法感知服务状态、重启后无法自动恢复。systemd 自 197 版本起提供了原生定时器(timer unit),把定时任务和服务管理统一到同一套体系中,日志、依赖、资源限制、失败重试全部内置,是当代运维的首选方案。

本文从 timer unit 的基本结构讲起,逐步演示如何用 systemd 定时器编排真实的服务器任务,并给出生产环境的最佳实践。

Timer Unit 的核心概念

一个定时任务由两个文件组成:

  • 服务单元(xxx.service):定义要执行的具体任务。
  • 定时器单元(xxx.timer):定义何时触发该服务。

定时器有两种触发模式:

模式 关键字 说明
单调时间 OnBootSec / OnActiveSec 自启动或上次触发后经过固定时长
日历时间 OnCalendar 按日期时间规则(类似 cron 表达式)触发

创建第一个定时任务

假设我们要每天凌晨 3 点备份数据库。先创建服务单元:

# /etc/systemd/system/backup.service
[Unit]
Description=Daily database backup

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh

再创建对应的定时器单元:

# /etc/systemd/system/backup.timer
[Unit]
Description=Run backup daily at 03:00

[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true

[Install]
WantedBy=timers.target

启用并启动:

systemctl daemon-reload
systemctl enable --now backup.timer

日历表达式的写法

systemd 的 OnCalendar 语法比 cron 更灵活,支持自然语言与通配符:

需求 表达式
每天 03:00 *-*-* 03:00:00
每周一 08:30 Mon *-*-* 08:30:00
每月 1 号 *-*-01 00:00:00
每 30 分钟 *-*-* *:00/30:00
开机后 5 分钟 OnBootSec=5min

用 systemd-analyze calendar '表达式' 可校验表达式并预览下一次触发时间。

Persistent 与精确控制

Persistent=true 是关键选项:当服务器在计划触发时刻处于关机状态时,启动后会补跑错过的任务。这对备份、同步类任务至关重要,避免漏执行。若需要严格控制两次触发之间不重叠,可配合 OnActiveSec 和 Unit= 指定目标服务。

[Timer]
Unit=backup.service
OnCalendar=*-*-* 03:00:00
Persistent=true
RandomizedDelaySec=60

RandomizedDelaySec 可打散触发时刻,避免多台机器在同一秒发起任务造成突刺。

任务输出与失败处理

与 cron 默认丢弃输出不同,systemd 定时任务的所有 stdout/stderr 都会进入 journal,可用 journalctl -u backup.service 查看。配合 ExecStart 与失败重试:

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
# 失败后最多重试 3 次,间隔 5 分钟
Restart=on-failure
RestartSec=5min
StartLimitBurst=3

管理命令速查

systemctl list-timers              # 列出所有定时器及下次触发时间
systemctl status backup.timer      # 查看定时器状态
systemctl start backup.service     # 立即手动执行一次任务
systemctl list-timer-units

总结

systemd 定时器把”什么时候跑”和”跑什么”拆成 timer 与 service 两个单元,天然继承了日志、依赖、资源限制和失败恢复能力。对需要可靠执行、错峰调度、错过补跑的服务器任务,建议优先使用 Timer Unit 而非传统 Cron。