深度解析OpenClaw内置Cron定时任务实现原理
摘要
OpenClaw 内置 Cron 定时任务的核心架构相当直白:进程内部持有一个 Cron 调度引擎,持续计算
OpenClaw 内置 Cron 定时任务的核心架构相当直白:进程内部持有一个 Cron 调度引擎,持续计算下一次触发时间点,一旦条件满足,立即将任务分发给执行器(线程池、协程队列或其他机制)执行。

Cron 定时任务配置与路径定位
OpenClaw 的 Cron 调度系统将任务文件存储于 .openclaw/cron 子目录中。
例如完整路径 /root/openclaw-docker/data/.openclaw/cron/jobs.json,其拼接规则为:OpenClaw 数据目录 + 固定子目录 .openclaw/cron/ + 固定文件名 jobs.json。
因此,你只需配置前半段 /root/openclaw-docker/data(即数据卷或工作目录),后半段由程序硬编码,不可更改。
那么 jobs.json 路径最终由谁决定?
1) 检查容器启动方式(Docker Compose 或 docker run)
docker ps --format 'table {{.Names}}t{{.Image}}t{{.Command}}t{{.Mounts}}'
2) 定位 OpenClaw 容器名称,导出其完整启动参数与挂载配置。
将以下命令中的 openclaw-docker-openclaw-gateway-1 替换为你实际的容器名,通过 docker inspect 输出的 Binds/Mounts 字段进行判断。
docker inspect openclaw-docker-openclaw-gateway-1 --format 'Name={{.Name}}
Cmd={{json .Config.Cmd}}
Entrypoint={{json .Config.Entrypoint}}
Env={{json .Config.Env}}
Binds={{json .HostConfig.Binds}}
Mounts={{json .Mounts}}'
假设输出示例如下:
Binds=["/root/openclaw-docker/data/.openclaw:/home/node/.openclaw:rw", ...]
Mounts=[{"Type":"bind","Source":"/root/openclaw-docker/data/.openclaw","Destination":"/home/node/.openclaw", ...}]
从输出可以清晰看到:
- 宿主机 路径
/root/openclaw-docker/data/.openclaw
通过 bind mount 映射至 - 容器内 路径
/home/node/.openclaw
由于 Cron 数据文件位于相对路径 .openclaw/cron/jobs.json,因此对应关系如下:
- 容器内路径:
/home/node/.openclaw/cron/jobs.json - 宿主机实际路径:
/root/openclaw-docker/data/.openclaw/cron/jobs.json
此外,需关注 Env 中的配置,例如:
Env=["HTTP_PROXY=http://172.17.0.1:1080","TERM=xterm-256color","NODE_OPTIONS=--use-env-proxy","NO_PROXY=localhost,127.0.0.1,172.17.0.0/16,10.0.0.0/8","HOME=/home/node"]
HOME=/home/node 是重要线索。多数程序默认使用 $HOME/.openclaw 存储数据,进一步验证容器内实际目录为 /home/node/.openclaw。
jobs.json 配置项详解
{
"version": 1,
"jobs": [
{
"id": "UUID-EXAMPLE-0001",
"agentId": "main",
"name": "定时执行脚本任务(示例)",
"enabled": true,
"createdAtMs": 1700000000000,
"updatedAtMs": 1700003600000,
"schedule": {
"kind": "every",
"everyMs": 43200000
},
"sessionTarget": "isolated",
"wakeMode": "next-heartbeat",
"payload": {
"kind": "agentTurn",
"message": "执行 bash /home/node//task.sh "" 2"
},
"state": {
"nextRunAtMs": 1700043200000,
"lastRunAtMs": 1700003600000,
"lastStatus": "ok",
"lastDurationMs": 16204
}
}
]
}
首先分析顶层字段:
version:数据格式版本号,用于兼容性及升级迁移。jobs:定时任务数组,每个元素代表一个独立任务。
每个 job 对象包含以下基础信息:
id:任务的唯一标识符(通常为 UUID)。agentId:指定执行任务的 agent 名称,例如main。name:任务显示名称,便于识别。enabled:是否启用。设为false时调度器将跳过该任务。createdAtMs与updatedAtMs:毫秒级 epoch 时间戳,记录创建和最后更新时间。
调度计划(schedule)
kind: "every":按固定时间间隔触发(非 Cron 表达式)。everyMs:间隔毫秒数,例如43200000对应 12 小时。
调度计划支持三种类型:
- at:一次性定时(如“30分钟后提醒”)。
- every:固定间隔重复(如“每5分钟执行一次”)。
- cron:标准 Cron 表达式(如
0 9 * * 1-5表示工作日上午9点)。
以下是一个 cron 调度示例:
"schedule": {
"kind": "cron",
"expr": "55 9 3 * *",
"tz": "Asia/Shanghai"
}
字段说明如下:
kind: "cron":指定使用 Cron 表达式触发。expr: "55 9 3 * *":标准 5 段 Cron 表达式(分、时、日、月、周)。tz: "Asia/Shanghai":明确时区,防止容器 UTC 默认时区导致偏差。
接下来说明会话与唤醒控制参数:
sessionTarget: "isolated":每次执行创建独立会话,避免干扰主对话上下文。wakeMode: "next-heartbeat":到达预定时间后,在下一次调度心跳 tick 中执行,存在微小延迟。
需区分两种执行模式:
- Main Session:将任务作为“用户消息”注入主对话,等同于手动发送消息触发 Agent。
- Isolated Session:创建独立会话运行复杂任务(如联网搜索、生成报告),完成后将结果汇报至主会话。
执行内容(payload)定义:
kind: "agentTurn":表示将一条消息回合投递至 agent 执行。message:发送给 agent 的指令文本,示例中是让 Agent 执行带参数的 bash 脚本。
注意:若 payload.kind 为 systemEvent,则仅在 OpenClaw 界面显示系统消息,不执行实际操作。
最后是运行状态(state),由系统运行后自动写入:
nextRunAtMs:下次触发时间(毫秒级)。lastRunAtMs:上次触发时间(毫秒级)。lastStatus:上次运行状态(例如ok)。lastDurationMs:上次执行耗时(毫秒级)。
配置方式与实操建议
操作极为简便:在 OpenClaw 对话中直接使用自然语言下达指令即可。OpenClaw 会自动创建 Cron 任务,并将数据持久化至 /home/node/.openclaw/cron 目录。
来源:互联网
本网站新闻资讯均来自公开渠道,力求准确但不保证绝对无误,内容观点仅代表作者本人,与本站无关。若涉及侵权,请联系我们处理。本站保留对声明的修改权,最终解释权归本站所有。