crontab 的最小调度单位是分钟,无法直接实现秒级或更高频的定时任务。当需要更频繁的检测(如每 30 秒、每 10 秒,甚至更高频率)时,systemd timer 是 Linux 系统下最推荐的方案。
以下是几种实现高频定时任务的对比和具体做法:
1. systemd timer(推荐)
systemd timer 可以精确到微秒级,支持多种触发模式(单调时间、实时时间、一次性等)。
创建三个文件:
A. Service 文件(/etc/systemd/system/my-task.service)
[Unit]
Description=My high-frequency task
[Service]
Type=oneshot
ExecStart=/usr/local/bin/my-script.sh
B. Timer 文件(/etc/systemd/system/my-task.timer)
[Unit]
Description=Run my-task every 30 seconds
[Timer]
# 系统启动后 10 秒首次执行
OnBootSec=10
# 之后每 30 秒执行一次
OnUnitActiveSec=30s
AccuracySec=1s
[Install]
WantedBy=timers.target
C. 启用并启动
sudo systemctl daemon-reload
sudo systemctl enable my-task.timer
sudo systemctl start my-task.timer
# 查看状态
sudo systemctl list-timers --all
关键参数:
OnUnitActiveSec表示"上次该服务激活后多久再次执行",配合AccuracySec=1s可确保精度。
2. 简单脚本 + sleep(适合容器或轻量场景)
如果不需要 systemd,可以用一个后台脚本:
#!/bin/bash
while true; do
/usr/local/bin/my-check.sh
sleep 30
done
配合 supervisor 或 nohup 托管到后台即可。缺点是进程管理不如 systemd 健壮。
3. 用 cron 模拟秒级(不推荐)
通过设置多个条目偏移执行来模拟秒级,比如每 10 秒:
* * * * * /path/to/task
* * * * * sleep 10; /path/to/task
* * * * * sleep 20; /path/to/task
* * * * * sleep 30; /path/to/task
* * * * * sleep 40; /path/to/task
* * * * * sleep 50; /path/to/task
缺点:hack 感强、日志分散、难以管理、sleep 期间进程挂起。
总结
| 方案 | 最小粒度 | 适用场景 |
|---|---|---|
| crontab | 1 分钟 | 常规定时任务 |
| systemd timer | 微秒级 | 系统级高频任务,推荐 |
| 脚本 + sleep | 秒级 | 简单容器/临时方案 |
| cron + sleep | 秒级 | 不推荐,维护困难 |
如果你的场景是系统服务监控、健康检查、高频数据采集,直接上 systemd timer 是最干净、最可控的方案。