You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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之类阻止多次启动的配置即可。

测试验证步骤

  1. 重新加载systemd配置:sudo systemctl daemon-reload
  2. 启用并启动定时器:sudo systemctl enable --now app.jobs-send.timer
  3. 查看定时器状态:sudo systemctl list-timers app.jobs-send.timer,可以看到下次触发时间每秒更新
  4. 实时查看服务日志:journalctl -u app.jobs-send.service -f,确认每秒都有新的服务实例启动

内容的提问来源于stack exchange,提问作者Anton Medvedev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:00:46