定时任务
了解项目内置的三项 Cloudflare Cron 任务,以及新增定时任务时需要同步维护的配置和入口。
Saavo 使用 Cloudflare Workers Cron Triggers 定期启动系统维护工作。当前项目注册了三条定时规则,分别负责权益周期检查、过期数据清理和统计数据保留期清理。
Cron 只负责“按时触发”。实际工作可能在当前定时请求中完成,也可能转换为 Reaction 事件后交给后台队列处理。排查问题时,需要继续确认后续执行链,而不能只看 Cloudflare 是否触发过 Cron。
内置定时任务
Cloudflare Cron 按 UTC 时区运行。当前配置如下:
| Cron 表达式 | 入口常量 | 触发时间 | 实际工作 |
|---|---|---|---|
0 0 * * * | ENTITLEMENT_CYCLE_CRON | 每天 00:00 UTC | 发出权益周期到期事件,并由后台任务处理到期记录 |
0 1 * * * | DATA_CLEANUP_CRON | 每天 01:00 UTC | 发出每日数据清理事件 |
30 */6 * * * | ANALYTICS_RETENTION_CRON | 每 6 小时的第 30 分钟 | 直接清理超过保留期的原始统计事件 |
Cron 表达式同时存在于两个位置:
wrangler.jsonc的triggers.crons,决定 Cloudflare 何时调用 Worker;src/entry/index.ts的常量和scheduledEntry分支,决定触发后执行哪项工作。
两处字符串必须完全一致。当前入口对未知表达式没有专门的错误或告警;如果只改了其中一处,Cloudflare 仍可能显示触发成功,但不会进入任何业务分支。
各项任务如何执行
处理权益周期
每天的 Cron 会查找下一条到期记录并发出 EntitlementCycleDueEvent。后续的 process-due-entitlement-cycles 是异步 Command,默认每批最多处理 30 条到期记录。
权益系统还会通过 Timer Durable Object 安排下一次精确重置,并预留 10 秒缓冲。因此,每日 Cron 主要承担定期检查和恢复作用,不是权益重置唯一依赖的计时器。
清理过期业务数据
数据清理任务以 UTC 日期生成稳定的幂等键,同一天重复触发只会产生一次有效事件。后台 Command 会清理过期的登录会话、邮箱验证会话、密码重置会话、OAuth 授权会话、失效的 OAuth 令牌和授权码,以及符合条件的已软删除 OAuth 客户端。
多数数据按“一天前”作为清理边界;已过期的双重验证设置会话会直接清理。不要通过提高 Cron 频率来改变保留策略,应在数据所有者所在的服务中调整规则。
清理过期统计数据
统计清理直接在 scheduled 运行时操作 ANALYTICS_DB,不进入 async-policy-task。它按批次和运行预算删除过期原始事件,一次未清完的部分会留给后续 Cron 继续处理。
保留天数由 config/deploy.ts 中的 analytics.retention.rawDays 管理。调整 rawDays 不需要修改 Cron 表达式。具体行为见访问统计。
添加定时任务
新增一项 Cron 时,应完成以下改动:
- 在
wrangler.jsonc的triggers.crons中添加表达式; - 在
src/entry/index.ts中定义对应常量; - 在
scheduledEntry中增加精确匹配的分支; - 复用入口已经创建的 scheduled
WorkerCtx,把业务规则交给所属 service; - 工作耗时较长、需要可靠重试或会调用外部服务时,用 Reaction Event / Command 进入现有后台任务管道;
- 为新分支补充触发、重复执行和失败场景测试。
不要在 scheduledEntry 中直接写 SQL,也不要从非 HTTP 入口调用 resolveFetchWorkerCtx。需要异步执行的业务可以通过 Reaction 入队,后续执行方式见后台任务。
定时触发不等于执行完成
权益周期和数据清理在触发后还要经过 Reaction 与队列。Cloudflare 的 Cron 记录成功,只能证明 scheduled 入口被调用;最终结果应结合 Reaction 执行记录、日志和数据状态判断。
部署与排查
部署后可在 Cloudflare 仪表盘确认 Cron 是否按时触发。对于进入 Reaction 的任务,还应检查:
/dashboard/reaction/events
/dashboard/reaction/commands统计数据清理不走 Reaction,应查看 scheduled 日志、告警以及 ANALYTICS_DB 中超过保留期的数据是否持续减少。
如果任务没有运行,按以下顺序排查:
- 对比
wrangler.jsonc与入口常量,确认字符串和空格完全一致; - 确认部署环境使用的是最新 Worker 配置;
- 确认 Cloudflare 已产生 Cron 触发记录;
- 检查入口日志是否进入预期分支;
- 对进入 Reaction 的任务检查事件、Command 和队列消费者;
- 对直接执行的统计清理检查数据库绑定、保留配置和积压告警。
上线检查
-
wrangler.jsonc中的三条表达式与入口常量完全一致。 - 已按 UTC 时区核对预期执行时间。
- 三项内置任务均在部署环境成功跑过至少一次。
- 权益周期和数据清理的 Reaction 事件、Command 均有正常记录。
- 统计清理没有持续出现新增速度高于清理速度的积压告警。
- 新增任务已覆盖重复触发、部分失败和安全重试场景。
- 定时入口只负责调度,没有越过 service 或 repository 直接操作业务数据库。