如何通过systemd实现服务每秒精准执行?允许重叠
看起来你遇到了systemd定时器无法每秒精准触发服务,还没法让任务重叠的问题——我来帮你梳理下原因和解决办法。
首先,你的现有配置里OnUnitActiveSec=1s的核心问题在于:systemd默认会跳过服务处于运行状态时的触发事件。也就是说,如果你的app.jobs-send.service运行时间超过1秒,下一次触发就会被推迟到上一个实例退出后,这就导致了日志里看到的非秒级间隔(大概率是你的服务每次运行时长超过了1秒)。另外,systemd默认的调度精度也可能让触发时间存在误差。
接下来是具体的修复方案:
修正定时器单元配置
把你的app.jobs-send.timer改成下面这样,重点用绝对时间调度实现每秒触发,同时拉满精度:
[Unit] Description=Send jobs every second [Timer] OnBootSec=1min # 用OnCalendar实现绝对每秒触发,不受服务运行状态影响 OnCalendar=*:*:* # 最大化触发精度,消除systemd默认的事件合并延迟 AccuracySec=1us # 禁止累积错过的任务,避免系统重启后批量执行积压任务 Persistent=false Unit=app.jobs-send.service [Install] WantedBy=multi-user.target
确保服务支持并行实例
你的服务单元需要允许同时运行多个实例,建议设置成oneshot类型(任务完成后自动退出,方便每次触发启动新实例),配置示例:
[Unit] Description=Send jobs to queue [Service] Type=oneshot # 替换成你的实际任务命令,确保命令可以安全并行执行 ExecStart=/path/to/your/job-send-script.sh RemainAfterExit=false [Install] WantedBy=multi-user.target
关键细节说明
- 为什么用
OnCalendar=*:*:*?它是基于系统时间的每秒触发,不管上一个服务实例是否还在运行,都会尝试启动新的实例,完美满足你「允许执行重叠」的需求。而OnUnitActiveSec依赖上一次服务启动时间,一旦服务运行超时就会推迟触发。 AccuracySec=1us是让systemd尽可能精准地在每秒开头触发,避免默认的调度延迟(默认可能有几秒的误差)。- 如果你的服务是长期运行的(不是一次性任务),只要确保你的服务命令本身支持多实例运行,并且服务单元没有设置
Restart之类阻止多次启动的配置即可。
测试验证步骤
- 重新加载systemd配置:
sudo systemctl daemon-reload - 启用并启动定时器:
sudo systemctl enable --now app.jobs-send.timer - 查看定时器状态:
sudo systemctl list-timers app.jobs-send.timer,可以看到下次触发时间每秒更新 - 实时查看服务日志:
journalctl -u app.jobs-send.service -f,确认每秒都有新的服务实例启动
内容的提问来源于stack exchange,提问作者Anton Medvedev
相关产品推荐
相关产品推荐

