8.2 定时作业设计与调度策略

本节聚焦无人值守作业的稳定性设计。目标不是“定时触发一次”,而是“重复执行也不会失控”。

[!NOTE] 本节讨论的防重入、幂等键和失败分流属于通用调度工程实践,适用于在宿主机上编排的外部定时作业。内建调度机制的具体开关与事件名可能随版本演进:以 --helpstatus --deep 与结构化日志的实际输出为自证入口。

具体例子:每日站会摘要自动化

假设团队希望每天早上 9:00,智能体自动从 Slack 和 Jira 拉取昨日进展,生成格式化的站会摘要并发到飞书群。这个作业的工程约束如下:

  • 幂等 :如果 9:00 的任务因网络抖动失败并在 9:05 重试,不能发两份日报到群里。

  • 防重入 :如果昨日数据量大导致生成耗时超过触发间隔,不能并发两个任务互相覆盖。

  • 可观测 :每次执行的耗时、成功/失败状态、发送目标都要留日志。

  • 可恢复 :Jira API 限流时,自动退避重试;Slack 鉴权失败时,终止并告警而不是死循环。

对应的 cron 配置与幂等键设计:

# crontab 条目

0 9 * * 1-5 /opt/openclaw/jobs/daily_standup.sh >> /var/log/oc_jobs/standup.log 2>&1
# daily_standup.sh 核心逻辑

WINDOW_START=$(date -d "today 09:00" +%s)
IDEM_KEY="daily_standup:v1:${WINDOW_START}"

# 幂等检查:同一窗口只执行一次

if redis-cli SET "oc_idem:${IDEM_KEY}" 1 NX EX 86400; then
  openclaw agent --message "生成今日站会摘要并发到飞书群 ops_daily"
else
  echo "已执行过,跳过"
fi

8.2.1 定时作业的四个工程约束

生产环境中的定时任务至少要满足:

  • 幂等:重复执行不产生重复副作用。

  • 防重入:上一次未完成时不能并发冲突。

  • 可观测:每次执行有状态、耗时和错误分类。

  • 可恢复:失败后有明确重试与人工接管路径。

8.2.2 防重入:分布式锁与实例所有权

当任务执行时间超过触发周期时,最常见问题是重入风暴。建议使用带 TTL 的分布式锁,并记录实例所有权。

释放锁时要校验锁持有者,避免误删其他实例锁。

8.2.3 幂等键:按调度窗口建唯一键

作业重试前,要先定义幂等键规则。推荐以“作业名 + 窗口开始时间”作为键。

只要幂等键一致,下游写操作就必须表现为“重复请求无副作用”。

8.2.4 失败分流:重试、终止、升级

错误应按类型分流。

  • 瞬时错误(超时、503、限流):有界重试,指数退避。

  • 配置错误(401/403、参数错误):立即终止并告警。

  • 数据冲突(写入不一致):冻结任务并触发人工介入。

不要把所有失败都当作“再试一次”。

8.2.5 运行验收与日常巡检

建议把定时作业纳入固定巡检。

验收时重点看三项:

  1. 是否出现重入。

  2. 是否出现重复副作用。

  3. 失败后是否能在规定时间内恢复或升级处理。

最后更新于