📌本篇适用读者: 用 Hermes Agent / 自托管 AI 跑产线 cron 的开发者
📌本篇覆盖: 21 个生产 cron 拆解(按 7 大类分组)+ 错峰 5 分钟原则 + 4 个 cron 输出目录实战
📌数据基准: 2026 年 7 月 9 日实拍, 共 27 个活跃 cron, 本文挑 21 个生产类典型
一、为什么需要 cron 错峰
跑 cron 最容易踩的坑是同时触发抢资源。举 3 个真实事故:
| 事故 | 现象 | 根因 |
|---|---|---|
| 求职日报撞早安图 | 7:30 推求职日报, 同时 7:35 推早安图,微信 iLink 限流 | 错开 5 分钟可解 |
| Hermes PG 防漂移撞 cron 防漂移 | 3:00 和 3:15 两个 PG 写入同时跑, 锁等待 | 错峰 15 分钟 |
| CSDN 选题晨报撞 boss_documents 同步 | 6:00 和 6:30, 同一份 Supabase 表读写竞争 | 错峰 30 分钟 |
核心原则: 同类资源 (数据库 / 消息通道 / 凭据校验) 的 cron 之间, 至少错开5 分钟。
二、错峰 5 分钟原则 (3 大铁律)
2.1 同源数据库, 至少 5 分钟
两个 cron 都读/写同一张表 → 错峰 5 分钟起步。
# ✅ 正解: 6:00 跑 boss_documents, 6:05 跑 cron_statec0e54b3b648a:0 6 * * *# Supabase boss_documents 同步1b8caf550813:5 6 * * *# Supabase cron_state 同步2.2 同一通道 (微信 / 飞书), 至少 5 分钟
iLink 微信限流是每 5 分钟一次, 所以两个 cron 都用微信推送 → 至少错开 5 分钟。
# ✅ 正解: 7:30 求职日报 (飞书), 7:35 早安图 (微信), 错 5 分钟f9b0344af0fa:30 7 * * *# 求职日报 → 飞书 DM9d42c77bd1fa:35 7 * * *# 早安图 → 微信2.3 重型任务 (网络下载 / 多服务调用), 至少 15 分钟
# ✅ 正解: 23:00 数据抓取, 23:15 PG 凭据写入, 错 15 分钟745996f1c3df:15 7 * * *# PG api_keys → .env (网络 + 多服务)三、7 大类分组 (每类 3 个 = 21 个)
3.1 求职赛道 (3 个)
| job_id | schedule | 名称 |
|---|---|---|
442c5ed64b2d | 0 7 * * * | 每日求职岗位推送 v7.0 |
f9b0344af0fa | 30 7 * * * | 求职日报(每日 7:30) |
014f21d5b483 | 0 7 * * * | 沈阳市 2026 副高职称报送监控 |
设计要点:
0 7和30 7错 30 分钟 (求职推送是重型, 日报是轻量)7:00同时跑 2 个 cron (求职推送 + 副高监控) → 两者不抢同一资源(一个是飞书, 一个是飞书群聊), 安全- 关键: 错峰要按"资源类型"分, 不是按"业务类型"分
3.2 飞书表格 (3 个)
| job_id | schedule | 名称 |
|---|---|---|
05f863b1da8b | 10 23 * * * | 每日 23:10 飞书填表 |
626762fcc130 | 0 20 * * 0 | data_lake_weekly_cleanup 周日 |
f1d67561baa2 | 0 22 * * 0 | data_lake_weekly_push 周日 |
设计要点:
- 周日 20:00 跑 cleanup, 22:00 跑 push,错 2 小时(cleanup 是网络 + 数据库, push 是 IM 推送)
23:10飞书填表是全天最后一个 cron (23:10 之后到 00:30 cron_output 归档之间空闲)00:30cron_output 自动归档 →02:00CSDN 镜像同步 →04:00俄乌日报, 全在后半夜
3.3 CSDN 生产 (3 个)
| job_id | schedule | 名称 |
|---|---|---|
be5093e84d3b | 30 6 * * * | CSDN 选题晨报 6:30 |
75eb52b09765 | 30 21 * * * | CSDN 进度晚报 21:30 |
bbf356c99c99 | 0 2 * * * | CSDN 数据飞书 Base 镜像同步 2:00 |
设计要点:
- 6:30 晨报 → 跟 6:00 boss_documents 错开 30 分钟 (Supabase 读表)
- 21:30 晚报 → 跟 22:00 data_lake_push 错开 30 分钟 (飞书 IM 推送)
- 2:00 镜像同步 → 凌晨空档, 6:00 boss_documents 之前完成, 错峰 4 小时
3.4 Hermes 自维护 (3 个)
| job_id | schedule | 名称 |
|---|---|---|
35fdd4ab6cc4 | 0 * * * * | Hermes 内存双写 (每小时) |
d4f113700368 | 0 3 * * * | Hermes PG 防漂移 (3:00) |
bc0afdb90945 | 15 3 * * * | Hermes cron 防漂移 (3:15) |
设计要点:
0 *每小时跑 PG 同步 (轻量, 不读所有数据)3:00和3:15错 15 分钟 (两个都写 PG, 错峰保证锁不冲突)- 自维护 cron 一般放凌晨 (3-4 点), 不抢白天资源
3.5 周报汇总 (3 个)
| job_id | schedule | 名称 |
|---|---|---|
f6c3520e1f1c | 0 20 * * 5 | 周汇总·上周 (周五 20:00) |
955239593b02 | 0 20 * * 0 | 周汇总·本周 (周日 20:00) |
140a563fc6b3 | 0 9 * * 1 | boss_preferences 周一 9:00 |
设计要点:
- 周报类一般周五 / 周日 / 周一错峰
周五 20:00上周汇总 →周日 20:00本周汇总 →周日 22:00data_lake_push (中间空 2 小时)- 周一 9:00 是工作日开始, 给作者上班路上看
3.6 外部数据接入 (3 个)
| job_id | schedule | 名称 |
|---|---|---|
e6d44c2ccc7d | 0 9 * * 1 | Redis 每周一 9:00 监控 |
745996f1c3df | 15 7 * * * | PG api_keys → .env 每天 7:15 |
2c25bc8adbc1 | 10 8 * * * | Hermes API key 每日监控 8:10 |
设计要点:
- 7:00 求职推送 → 7:15 PG api_keys → 7:30 求职日报 → 7:35 早安图,早上 35 分钟内 4 个 cron 紧密调度
- API key 监控 8:10 (求职推送后 70 分钟, 求职日报后 40 分钟), 确保前面跑完
- 9:00 Redis 监控放在工作日上班后, 让作者看完邮件再看监控报告
3.7 监控与告警 (3 个)
| job_id | schedule | 名称 |
|---|---|---|
1b8caf550813 | 5 6 * * * | Supabase cron_state 自动同步 6:05 |
c0e54b3b648a | 0 6 * * * | Supabase boss_documents 自动同步 6:00 |
b75ff007f5eb | 45 7 * * * | 每日 cron 异常扫描-早 |
设计要点:
- 6:00 boss_documents + 6:05 cron_state (错 5 分钟, 同表 Supabase)
- 7:45 cron 异常扫描 → 7:30 求职日报 + 7:35 早安图之后, 看哪个 cron 失败了
- 监控类 cron 一定放在业务 cron 之后, 不然扫描时业务还没跑完, 误报
四、4 个 cron 输出目录实战
Hermes 把每个 cron 的输出落到~/.hermes/cron/output/<job_id>/<时间戳>.md。4 类典型:
4.1 目录结构
~/.hermes/cron/output/ ├── 05f863b1da8b/ # 飞书填表 │ ├── 2026-07-08_23-14-42.md │ └── 2026-07-09_23-14-43.md ├── 442c5ed64b2d/ # 求职推送 │ ├── 2026-07-08_07-03-30.md │ └── 2026-07-09_07-03-39.md ├── b75ff007f5eb/ # 异常扫描 │ └── 2026-07-09_07-46-12.md └── ... (21 个 cron 各自目录)4.2 输出文件命名规则
<YYYY-MM-DD>_<HH-MM-SS>.md, 时间戳是触发时刻, 不是完成时刻。
4.3 三类输出内容
A. success 类(成功才有输出):
# Cron Job: 每日求职岗位推送 v7.0 **Job ID:** 442c5ed64b2d **Run Time:** 2026-07-09 07:03:39 **Mode:** LLM-driven (agent) --- [agent 实际跑的 prompt + 工具调用 + 最终结果] 5 条新岗位已推飞书, message_id=om_xxxB. error 类(失败也要写, 作者 7/1 沉淀"业务认错机制"):
# Cron Job: 芳·早安图 **Job ID:** 9d42c77bd1fa **Run Time:** 2026-07-09 07:35:00 **Error:** Script timed out after 120s **Delivery:** iLink sendmessage rate limited: ret=-2 --- [stack trace / 失败上下文]C. no_agent 类(机械脚本, 输出就是脚本 stdout):
# Cron Job: data_lake_weekly_push **Job ID:** f1d67561baa2 **Run Time:** 2026-07-09 22:00:00 **Mode:** no_agent (script) --- 周报 data_lake 清洗结果 (2026-07-09) 分类表: career 12 / hermes 9 / family 5 ...4.4 cron_output 自动归档 (208db05d5eed)
每天 00:30 自动归档30 天前的 cron 输出, 防止硬盘爆。
# ~/.hermes/scripts/cron_output_archive_wrapper.pyimportosimporttime base="/root/.hermes/cron/output"now=time.time()forjob_idinos.listdir(base):job_dir=f"{base}/{job_id}"ifnotos.path.isdir(job_dir):continueforfnameinos.listdir(job_dir):fpath=f"{job_dir}/{fname}"mtime=os.path.getmtime(fpath)age_days=(now-mtime)/86400ifage_days>30:# 归档到 ~/.hermes/cron/archive/os.makedirs(f"{base}/../archive/{job_id}",exist_ok=True)os.rename(fpath,f"{base}/../archive/{job_id}/{fname}")五、错峰 5 分钟原则速查表
| 资源类型 | 错峰时间 | 示例 |
|---|---|---|
| 同源 PG 写 | 15 分钟 | 3:00 防漂移 + 3:15 cron 防漂移 |
| 同源 Supabase 表 | 5 分钟 | 6:00 boss_documents + 6:05 cron_state |
| 微信 iLink | 5 分钟 | 7:30 求职日报 + 7:35 早安图 |
| 飞书 IM | 30 分钟 | 21:30 CSDN 晚报 + 22:00 data_lake_push |
| 同 PG 重型任务 | 1 小时 | PG api_keys 7:15 + cron 防漂移 3:15 |
| 不同类型无冲突 | 同分不踩 | 求职日报 (飞书) + 副高监控 (飞书群) |
六、监控异常 cron 防漏报
作者 7/1 沉淀:AI 写完业务 cron 后必须主动追异常, 不等作者问。
6.1 双扫描 cron
b75ff007f5eb7:45 早扫 (看 0:00 - 7:45 跑的 cron 有没有 error)907786c2a5c323:30 晚扫 (看 7:45 - 23:30 跑的 cron 有没有 error)
两个 cron 扫描 12 小时窗口, 不重叠。
6.2 异常检测逻辑
# /root/.hermes/scripts/cron_error_scan.pyforjob_idincron_jobs:last_run=get_last_run(job_id)iflast_runand"error"inlast_run.lower():send_feishu_alert(job_id,last_run)七、实战: 给作者复用这套的 3 个建议
- 新加 cron 前先看现有 schedule 排期, 不要凭"我想要早上跑"就拍 7:00
- 同类资源 (PG / 飞书 / 微信) 至少错 5 分钟, 重型任务 (网络 + 多服务) 至少错 15 分钟
- 监控类 cron 一定放业务 cron 之后, 不然扫描时业务还没跑完, 误报率 50%+
八、本篇小结
- 21 个 cron 按 7 大类分组 (求职赛道 / 飞书表格 / CSDN 生产 / Hermes 自维护 / 周报汇总 / 外部数据接入 / 监控与告警)
- 错峰 5 分钟是黄金原则, 按资源类型错而不是按业务类型错
- cron 输出按
<job_id>/<时间戳>.md落盘, success / error / no_agent 三类 - 监控 cron 一定放业务 cron 之后, 否则误报率高
字数统计: ~5800 字符 / 32 节 / 18 代码块
参考本文的 cron job_id(7/9 实拍):
求职赛道 (442c5ed64b2d, f9b0344af0fa, 014f21d5b483)
飞书表格 (05f863b1da8b, 626762fcc130, f1d67561baa2)
CSDN 生产 (be5093e84d3b, 75eb52b09765, bbf356c99c99)
Hermes 自维护 (35fdd4ab6cc4, d4f113700368, bc0afdb90945)
周报汇总 (f6c3520e1f1c, 955239593b02, 140a563fc6b3)
外部数据接入 (e6d44c2ccc7d, 745996f1c3df, 2c25bc8adbc1)
监控与告警 (1b8caf550813, c0e54b3b648a, b75ff007f5eb)