用 systemd timer 替代 crontab:更好排查的 Linux 定时任务实践

举报
yd_275727902 发表于 2026/10/28 09:18:51 2026/10/28
【摘要】 很多人在云服务器上跑定时任务的第一反应是 crontab -e。cron 简单好用,但出了问题时常常让人摸不着头脑:任务到底跑没跑?输出去哪了?环境变量为什么和手动执行不一样?这篇文章分享一套用 systemd timer 管理定时任务的做法,适合 EulerOS、CentOS 7+、Ubuntu 16.04+ 等使用 systemd 的发行版。一、cron 常见的三个坑1. 日志难找:输出...

很多人在云服务器上跑定时任务的第一反应是 crontab -e。cron 简单好用,但出了问题时常常让人摸不着头脑:任务到底跑没跑?输出去哪了?环境变量为什么和手动执行不一样?这篇文章分享一套用 systemd timer 管理定时任务的做法,适合 EulerOS、CentOS 7+、Ubuntu 16.04+ 等使用 systemd 的发行版。

一、cron 常见的三个坑

1. 日志难找:输出默认发到本地邮件,很多机器没配置邮件,结果输出直接丢失。

2. 环境不一致:cron 的 PATH 很短,脚本里调用 python3、docker 等命令时容易出现 command not found。

3. 错过就错过:机器在任务时间点关机或重启,这次执行不会补跑。

二、systemd timer 的基本结构

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

- xxx.service:定义“做什么”

- xxx.timer:定义“什么时候做”

以每天凌晨 2 点清理 7 天前的日志为例。

/etc/systemd/system/log-clean.service:

[Unit]
Description=Clean old application logs

[Service]
Type=oneshot
ExecStart=/usr/bin/find /var/log/myapp -name "*.log" -mtime +7 -delete

/etc/systemd/system/log-clean.timer:

[Unit]
Description=Run log-clean daily

[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
RandomizedDelaySec=300

[Install]
WantedBy=timers.target

说明:

- Persistent=true:如果到点时机器正好关机,开机后会补跑一次,解决了 cron 错过不补的问题。

- RandomizedDelaySec=300:在 5 分钟内随机延迟,避免多台机器同一时刻打满后端或存储。

三、启用与验证

systemctl daemon-reload
systemctl enable --now log-clean.timer
systemctl list-timers --all | grep log-clean

list-timers 会直接列出下次执行时间(NEXT)和上次执行时间(LAST),这比在 cron 里猜要直观得多。

想立刻测试一次,不用等到点:

systemctl start log-clean.service

四、排查:日志统一进 journal

任务的标准输出和错误都会自动进 journald:

journalctl -u log-clean.service --since today
systemctl status log-clean.service

退出码、耗时、报错一目了然。失败时 systemctl --failed 也能看到。

五、几个实用配置

1. 环境变量:在 [Service] 中用 Environment=KEY=VALUE 或 EnvironmentFile=/etc/myapp/env 明确指定,不再依赖登录 shell。

2. 超时保护:TimeoutStartSec=30min,防止脚本卡死一直占资源。

3. 资源限制:CPUQuota=50%、MemoryMax=512M,避免定时任务影响线上业务。

4. 失败告警:OnFailure=notify@%n.service,搭配一个发送通知的模板 service,就能在任务失败时调用告警脚本。

5. 以普通用户运行:User=appuser,遵循最小权限原则。

六、OnCalendar 写法速查

- 每小时:hourly 或 *-*-* *:00:00

- 每天 2 点:*-*-* 02:00:00

- 每周一 9 点:Mon *-*-* 09:00:00

- 每 15 分钟:*:0/15

可以用 systemd-analyze calendar "Mon *-*-* 09:00:00" 校验表达式并查看下次触发时间。

七、什么时候还用 cron

如果只是个人机器上一行就能搞定的简单任务,cron 依然足够;但对生产环境中需要可观测、可补跑、可限制资源的任务,systemd timer 更省心。

总结:把定时任务从 crontab 迁到 systemd timer,主要收益是可观测(list-timers、journalctl)、可靠(Persistent 补跑)和可控(超时、资源限制、失败回调)。在云服务器上做运维时,不妨从一个日志清理任务开始试试。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。