systemd timer 怎么用 RandomizedDelaySec 错峰执行
RandomizedDelaySec= 的作用,是在 systemd timer 算出的基准触发时间之后,再增加一段均匀分布的随机延迟。比如每天 02:00 运行的任务配置 RandomizedDelaySec=30min,实际触发会落在 02:00 到 02:30 之间,从而减少多台机器同时访问数据库、对象存储或更新服务器造成的瞬时压力。
官方文档:https://www.freedesktop.org/software/systemd/man/latest/systemd.timer.html
OnCalendar=或其他定时条件负责确定基准时刻,RandomizedDelaySec=只在其上增加随机延迟。- 随机值默认在每次触发前重新选择;需要每台机器保持固定偏移时,再启用
FixedRandomDelay=true。 AccuracySec=允许 systemd 合并附近的定时事件,它与随机延迟解决的是不同问题。
前置条件:先确认版本与任务边界
RandomizedDelaySec= 从 systemd 229 起可用,FixedRandomDelay= 从 systemd 247 起可用。先查看系统版本和 timer 手册,避免在较旧发行版上直接套用后文的扩展配置。
# 查看当前 systemd 版本,并确认 timer 手册包含目标参数
systemd --version
man systemd.timer
这个实验假设要每天执行一次缓存预热脚本。脚本本身应当可重复执行,并能在多个实例偶尔重叠时保持安全。随机延迟只降低碰撞概率,不提供分布式锁,也不保证不同主机绝对不会在同一秒触发。
步骤一:创建一次性 service unit
timer 负责决定何时激活,真正的命令放在同名 service 中。创建 /etc/systemd/system/cache-warmup.service:
# /etc/systemd/system/cache-warmup.service
[Unit]
Description=预热应用缓存
[Service]
Type=oneshot
# 使用固定绝对路径,避免依赖交互式 Shell 的 PATH。
ExecStart=/usr/local/sbin/cache-warmup
Type=oneshot 适合运行完成后退出的批处理任务。文件名为 cache-warmup.service,后面创建同名 cache-warmup.timer 后,timer 默认就会激活这个 service,不需要额外写 Unit=。
步骤二:先确定没有随机化的基准计划
先把基准计划写清楚,再设置错峰窗口。下面的日历表达式表示每天 02:00:00。可以用 systemd-analyze calendar 检查表达式解析结果,这一步只验证日历条件,不会展示最终随机偏移。
# 检查 OnCalendar 表达式会匹配哪些基准时刻
systemd-analyze calendar '*-*-* 02:00:00'
如果每台机器的基准时刻不同,就很难判断随机窗口到底覆盖哪里。保持统一的 OnCalendar=,再用 RandomizedDelaySec= 分散实际触发,配置更容易审计。
步骤三:在 timer 中加入随机延迟窗口
创建 /etc/systemd/system/cache-warmup.timer。以下配置把每日 02:00 作为基准,并把每次执行随机推迟 0 到 30 分钟:
# /etc/systemd/system/cache-warmup.timer
[Unit]
Description=每天错峰执行缓存预热
[Timer]
# 每天 02:00 是基准时刻,实际执行会在此后随机延迟。
OnCalendar=*-*-* 02:00:00
RandomizedDelaySec=30min
# 缩小事件合并窗口,让 30 分钟随机范围真正用于分散触发。
AccuracySec=1s
# 关机期间错过计划时,启动后补一次任务。
Persistent=true
[Install]
WantedBy=timers.target
官方文档说明,RandomizedDelaySec= 默认是 0,也就是不增加随机延迟。随机值会加在“下一次基准触发时间”和“服务管理器启动时间”两者中较晚的那个时间点上。对于普通日历 timer,可以把它理解为:先得到计划时刻,再向后推迟最多 30 分钟。

AccuracySec= 不是另一个随机窗口。它允许 systemd 把邻近的 timer 事件合并,以减少系统唤醒次数;RandomizedDelaySec= 则用于主动拉开相似 timer 的触发时间。官方建议在希望最大化分散效果时把 AccuracySec= 设得很小。这里采用 1 秒,已经适合多数分钟级错峰任务;若需要严格遵循最小合并窗口,可以按官方建议评估 1us。
步骤四:重新加载并启用 timer
写入两个 unit 后,让 systemd 重新读取配置,并同时启用、启动 timer:
# 重新加载 unit 文件,然后立即启动并设置为开机启用
sudo systemctl daemon-reload
sudo systemctl enable --now cache-warmup.timer
enable --now 同时完成两个动作:创建开机启用所需的链接,并在当前系统中启动 timer。只运行 enable 不等于当前立即开始等待;只运行 start 也不会自动获得下次开机启用状态。
步骤五:检查下一次触发时间与参数
启用后先看 timer 列表中的 NEXT 字段,再用 systemctl show 查看底层属性。list-timers 展示的是 systemd 已计算的下一次触发时间,因此它已经包含本轮随机延迟和精度处理的结果。
# 查看下一次实际触发时间,并核对随机延迟相关属性
systemctl list-timers cache-warmup.timer
systemctl show cache-warmup.timer \
-p NextElapseUSecRealtime \
-p RandomizedDelayUSec \
-p AccuracyUSec \
-p FixedRandomDelay
unit 文件里的高层配置名通常以 Sec 结尾,而 systemctl show 暴露的底层 D-Bus 属性常以 USec 结尾。两者表达同一个设置,只是底层属性使用微秒单位。若 NEXT 不在预期范围,优先检查 OnCalendar= 是否写对、旧 drop-in 是否覆盖配置,以及 timer 是否已经重新加载。
任务触发后,用 service 日志确认脚本是否成功执行:
# 查看本次和历史执行日志,失败时保留完整上下文
journalctl -u cache-warmup.service --since today
systemctl status cache-warmup.service
扩展实验:需要稳定错峰时启用 FixedRandomDelay
默认情况下,timer 每次迭代都会重新选择随机延迟。若希望同一台机器上的同一个 timer 总是保持稳定偏移,可以加入 FixedRandomDelay=true:
# /etc/systemd/system/cache-warmup.timer.d/stable-offset.conf
[Timer]
# 在 RandomizedDelaySec 窗口内,为该主机和 unit 保持稳定偏移。
FixedRandomDelay=true
这个固定值由 machine ID、服务管理器的用户标识以及 timer unit 名称共同派生。它只在 RandomizedDelaySec 不为 0 时生效。对批量部署的服务器而言,各主机通常会得到不同偏移,而单机自己的触发抖动会更小。

启用 drop-in 后仍需重新加载并重启 timer,才能重新计算等待状态:
# 应用 drop-in,并让 timer 使用新的固定随机策略
sudo systemctl daemon-reload
sudo systemctl restart cache-warmup.timer
systemctl list-timers cache-warmup.timer
Persistent、AccuracySec 与随机延迟怎么配合
| 参数 | 解决的问题 | 推荐判断 |
|---|---|---|
OnCalendar= | 定义基准计划 | 先用 systemd-analyze calendar 验证 |
RandomizedDelaySec=30min | 把相似任务分散到一个窗口 | 窗口应小于业务允许的最晚完成时间 |
AccuracySec=1s | 控制 systemd 合并 timer 事件的范围 | 强调错峰时设小,强调省电时可保留较大值 |
FixedRandomDelay=true | 让同一 timer 的随机偏移保持稳定 | 批量主机希望固定分片时启用 |
Persistent=true | 机器关机期间错过日历任务后补跑 | 任务允许开机后补执行时启用 |
Persistent=true 可能让多台刚开机的机器都产生补跑需求,而随机延迟可以继续降低它们同时启动任务的概率。但它仍不是集中式协调器:如果任务对并发有硬限制,还应在服务端设置队列、租约或互斥机制。
清理实验 unit
不再需要该实验时,先停用 timer,再删除 unit 和 drop-in,最后重新加载 systemd。不要只删除文件却留下仍在内存中等待的 timer。
# 停止并取消开机启用,然后移除本次实验配置
sudo systemctl disable --now cache-warmup.timer
sudo rm /etc/systemd/system/cache-warmup.timer
sudo rm /etc/systemd/system/cache-warmup.service
sudo rm -rf /etc/systemd/system/cache-warmup.timer.d
sudo systemctl daemon-reload
相关问题
RandomizedDelaySec 会提前执行任务吗?
不会。它是在已确定的基准触发时间之后增加非负随机延迟,不会把任务提前到 OnCalendar 之前。
为什么多台主机仍可能同时执行?
各 timer 独立选择随机值,不存在跨主机协调,因此只能降低碰撞概率,不能保证完全不重合。窗口太小或主机数量很多时,仍应使用服务端限流或分布式锁。
为什么修改 timer 后 NEXT 没变化?
先执行 systemctl daemon-reload,再重启 timer。还要用 systemctl cat cache-warmup.timer 检查发行版自带 unit 或旧 drop-in 是否覆盖了当前配置。
Go cookiejar.Options 怎么接入公共后缀判断
- 上一篇
- Go cookiejar.Options 怎么接入公共后缀判断
- 下一篇
- tapaim系统版本要求是什么?无系统要求字段与设备兼容边界说明
-
- 文章 · linux | 3小时前 |
- Linux core_pattern 管道处理程序怎么接收崩溃信息
- 132浏览 收藏
-
- 文章 · linux | 5小时前 | Linux io_uring 异步取消 IORING_OP_ASYNC_CANCEL
- Linux io_uring 怎么取消尚未完成的请求
- 395浏览 收藏
-
- 文章 · linux | 7小时前 | Linux · Linux user namespace uid_map
- Linux user namespace 的 uid_map 怎么配置
- 231浏览 收藏
-
- 文章 · linux | 10小时前 | 网络安全 · Linux 防火墙 nftables 动态集合 set timeout gc-interval
- Linux nftables 动态集合怎么设置元素过期时间
- 470浏览 收藏
-
- 文章 · linux | 13小时前 | Linux · 内存管理 · Linux OOM oom_score_adj 进程回收
- Linux oom_score_adj 怎么控制进程被回收优先级
- 306浏览 收藏
-
- 文章 · linux | 17小时前 | 进程管理 · Linux cgroup v2 cgroup.freeze cgroup.events cgroup.procs 进程冻结
- Linux cgroup v2 怎么冻结并恢复一组进程
- 467浏览 收藏
-
- 文章 · linux | 19小时前 | systemd service ReadWritePaths ProtectSystem 文件系统沙箱 Linux服务加固
- systemd ProtectSystem 与 ReadWritePaths 怎么组合
- 485浏览 收藏
-
- 文章 · linux | 22小时前 | Linux · Linux systemd-journald journald.conf RateLimitIntervalSec RateLimitBurst 日志限速
- systemd-journald 日志限速丢弃怎么调整
- 208浏览 收藏
-
- 文章 · linux | 1天前 |
- journalctl 怎么按服务某次 invocation 筛选日志
- 466浏览 收藏
-
- 文章 · linux | 1天前 | Linux · systemd Restart RestartMode 依赖单元
- systemd RestartMode 怎么减少依赖单元连锁失败
- 239浏览 收藏
-
- 文章 · linux | 1天前 | 定时任务 · Linux · 运维 · Cron OnCalendar Persistent systemd timer systemd-analyze calendar
- systemd timer 替代 cron 的日历表达式配置
- 364浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 334次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 391次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 388次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 353次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 176次使用
-
- Linux vmstat 如何分辨内存抖动与磁盘等待:si、so、wa 与复测顺序
- 2026-08-30 501浏览
-
- Linux搭建vsftpdFTP服务器教程
- 2026-04-30 501浏览
-
- Shell脚本安装教程:.sh一键安装指南
- 2026-03-16 501浏览
-
- Linux清空文件内容的几种方法
- 2025-12-01 501浏览
-
- Linux命令行下载文件技巧
- 2025-11-23 501浏览

