mcpField
C
cloudflare-cron-triggers

cloudflare-cron-triggers

github.com/secondsky云与 DevOps240226 次安装5 周前更新
代码仓库

关于 cloudflare-cron-triggers

面向 Cloudflare Workers 开发者的 Cron Triggers 技能,指导定时处理器的实现、配置、测试和部署。内容包括 Cron 表达式、常见集成模式及问题排查。

主要功能

  1. 01定时处理器实现指导
  2. 02五字段 Cron 表达式参考
  3. 03Wrangler 触发器配置
  4. 04本地测试与部署指导
  5. 05多计划和集成模式
  6. 06常见错误排查

适用场景

  1. 01定时执行数据库清理
  2. 02按计划生成报告
  3. 03用多个计划分派不同任务
  4. 04本地验证定时处理器

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/secondsky/claude-skills --skill cloudflare-cron-triggers

安装后在 Claude Code 中输入/cloudflare-cron-triggers确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
common-patterns.md
cron-expressions-reference.md
integration-patterns.md
testing-guide.md
wrangler-config.md
templates/
basic-scheduled.ts
hono-with-scheduled.ts
multiple-crons.ts
scheduled-with-bindings.ts
wrangler-cron-config.jsonc

详细介绍

Cloudflare Cron Triggers

状态:生产就绪 ✅ 最后更新:2025-11-25 依赖项:cloudflare-worker-base(用于 Worker 设置) 最新版本:[email protected],@cloudflare/[email protected]


快速入门(5 分钟)

1. 向 Worker 添加定时处理程序

src/index.ts:

export default {
  async scheduled(
    controller: ScheduledController,
    env: Env,
    ctx: ExecutionContext
  ): Promise<void> {
    console.log('Cron job executed at:', new Date(controller.scheduledTime));
    console.log('Triggered by cron:', controller.cron);

    // Your scheduled task logic here
    await doPeriodicTask(env);
  },
};

重要原因:

  • 处理程序必须准确命名为 scheduled(不能是 scheduledHandler 或 onScheduled)
  • 必须在默认导出对象中导出
  • 必须使用 ES modules 格式(不能使用 Service Worker 格式)
2. 在 Wrangler 中配置 Cron Trigger

wrangler.jsonc:

{
  "name": "my-scheduled-worker",
  "main": "src/index.ts",
  "compatibility_date": "2025-10-23",
  "triggers": {
    "crons": [
      "0 * * * *"  // Every hour at minute 0
    ]
  }
}

关键事项:

  • Cron 表达式使用 5 个字段:minute hour day-of-month month day-of-week
  • 所有时间均为 UTC(不进行时区转换)
  • 更改最多需要 15 分钟才能在全球范围内生效
3. 在本地测试
# Enable scheduled testing
bunx wrangler dev --test-scheduled

# In another terminal, trigger the scheduled handler
curl "http://localhost:8787/__scheduled?cron=0+*+*+*+*"

# View output in wrangler dev terminal

测试提示:

  • 只有使用 --test-scheduled 标志时,/__scheduled 端点才可用
  • 可以在查询参数中传入任意 Cron 表达式
  • Python Workers 使用 /cdn-cgi/handler/scheduled
4. 部署
npm run deploy
# or
bunx wrangler deploy

部署后:

  • 更改最多可能需要 15 分钟才能生效
  • 查看仪表板:Workers & Pages > [你的 Worker] > Cron Triggers
  • 在 Logs 选项卡中查看过往执行记录

何时加载参考资料

用户提及时立即加载:

  • cron-expressions-reference.md → “cron 语法”、“计划格式”、“表达式”、“分钟 小时 天”、“每隔 X 分钟”
  • common-patterns.md → “示例”、“用例”、“模式”、“实际应用”、“数据库清理”、“报告生成”、“如何”
  • integration-patterns.md → “实现”、“Hono”、“多个触发器”、“绑定”、“工作流”、“错误处理”
  • wrangler-config.md → “配置”、“wrangler.jsonc”、“多个 crons”、“特定环境”、“开发 测试 生产”
  • testing-guide.md → “测试”、“本地开发”、“__scheduled”、“单元测试”、“curl”、“调试”

以下情况主动加载:

  • 构建新的定时任务 → 加载 integration-patterns.md
  • 配置 wrangler.jsonc → 加载 wrangler-config.md
  • 调试 Cron 表达式 → 加载 cron-expressions-reference.md
  • 在本地测试 → 加载 testing-guide.md
  • 查找示例 → 加载 common-patterns.md

Cron 表达式语法

五字段格式
* * * * *
│ │ │ │ │
│ │ │ │ └─── Day of Week (0-6, Sunday=0)
│ │ │ └───── Month (1-12)
│ │ └─────── Day of Month (1-31)
│ └───────── Hour (0-23)
└─────────── Minute (0-59)
特殊字符
字符含义示例
*每个* * * * * = 每分钟
,列表0,30 * * * * = 每小时的 :00 和 :30
-范围0 9-17 * * * = 上午 9 点到下午 5 点之间每小时
/步长*/15 * * * * = 每 15 分钟
常见模式
# Every minute
* * * * *

# Every 5 minutes
*/5 * * * *

# Every 15 minutes
*/15 * * * *

# Every hour at minute 0
0 * * * *

# Every hour at minute 30
30 * * * *

# Every 6 hours
0 */6 * * *

# Every day at midnight (00:00 UTC)
0 0 * * *

# Every day at noon (12:00 UTC)
0 12 * * *

# Every day at 3:30am UTC
30 3 * * *

# Every Monday at 9am UTC
0 9 * * 1

# Every weekday at 9am UTC
0 9 * * 1-5

# Every Sunday at midnight UTC
0 0 * * 0

# First day of every month at midnight UTC
0 0 1 * *

# Twice a day (6am and 6pm UTC)
0 6,18 * * *

# Every 30 minutes during business hours (9am-5pm UTC, weekdays)
*/30 9-17 * * 1-5

关键事项:仅限 UTC 时区

  • 所有 Cron Trigger 均按 UTC 时间执行
  • 不支持时区转换
  • 请手动将本地时间转换为 UTC
  • 示例:太平洋标准时间上午 9 点 = UTC 下午 5 点(夏令时期间为次日)

ScheduledController 接口

interface ScheduledController {
  readonly cron: string;           // The cron expression that triggered this execution
  readonly type: string;           // Always "scheduled"
  readonly scheduledTime: number;  // Unix timestamp (ms) when scheduled
}
属性
controller.cron(string)

触发此次执行的 Cron 表达式。

export default {
  async scheduled(controller: ScheduledController, env: Env): Promise<void> {
    console.log(`Triggered by: ${controller.cron}`);
    // Output: "Triggered by: 0 * * * *"
  },
};

**用例:**区分多个 Cron 计划(参见“多个 Cron Trigger”模式)。

controller.type(string)

Cron 触发的执行始终返回 "scheduled"。

if (controller.type === 'scheduled') {
  // This is a cron-triggered execution
}
controller.scheduledTime(number)

此次执行计划运行时的 Unix 时间戳(自纪元起的毫秒数)。

export default {
  async scheduled(controller: ScheduledController): Promise<void> {
    const scheduledDate = new Date(controller.scheduledTime);
    console.log(`Scheduled for: ${scheduledDate.toISOString()}`);
    // Output: "Scheduled for: 2025-10-23T15:00:00.000Z"
  },
};

注意:这是计划时间,而非实际执行时间。由于系统负载,实际执行可能略有延迟(通常 <1 秒)。


执行上下文

export default {
  async scheduled(
    controller: ScheduledController,
    env: Env,
    ctx: ExecutionContext  // ← Execution context
  ): Promise<void> {
    // Use ctx.waitUntil() for async operations that should complete
    ctx.waitUntil(logToAnalytics(env));
  },
};
ctx.waitUntil(promise: Promise<any>)

扩展执行上下文,以便在处理程序返回后等待异步操作完成。

用例:

  • 记录日志到外部服务
  • 分析跟踪
  • 清理操作
  • 非关键后台任务
export default {
  async scheduled(controller: ScheduledController, env: Env, ctx: ExecutionContext): Promise<void> {
    // Critical task - must complete before handler exits
    await processData(env);

    // Non-critical tasks - can complete in background
    ctx.waitUntil(sendMetrics(env));
    ctx.waitUntil(cleanupOldData(env));
    ctx.waitUntil(notifySlack({ message: 'Cron completed' }));
  },
};

**重要:**第一个失败的 waitUntil() 将作为状态记录在仪表板日志中。


集成模式

6 种可用于生产环境的 cron 模式:

  1. 独立 Worker 与 Cron - 用于后台任务(数据库清理、报告生成)的单个定时函数
  2. Hono + Cron 组合 - 在一个 Worker 中提供 HTTP 端点和定时任务,共享绑定并降低成本
  3. 多个 Cron 触发器 - 使用 controller.cron 路由执行,为不同任务设置不同的计划
  4. 访问绑定 - 在定时函数中使用 D1、KV、R2、AI、Vectorize、Queues、Workflows、Durable Objects
  5. 与 Workflows 集成 - 按计划触发复杂的长时间运行多步骤工作流
  6. 错误处理最佳实践 - 全面的错误处理,包括重试逻辑、告警(Slack/电子邮件)、故障日志记录和监控

加载 references/integration-patterns.md,查看包含代码示例、配置详情和最佳实践的完整实现。


Wrangler 配置

在 wrangler.jsonc 的 triggers.crons 数组中添加 cron 触发器。每个触发器都需要一个 cron 表达式。支持多个 cron(免费版:最多 3 个,付费版:限制更高)以及适用于开发/暂存/生产部署的环境特定配置。

加载 references/wrangler-config.md,查看完整的配置示例,包括多个触发器、环境特定计划、时区处理和移除流程。


测试与开发

运行 bunx wrangler dev --test-scheduled,使用 /__scheduled 端点在本地测试定时函数;然后通过 curl "http://localhost:8787/__scheduled?cron=0+*+*+*+*" 触发处理程序(在 cron 表达式中使用 + 代替空格)。

加载 references/testing-guide.md,查看完整的测试策略、本地开发设置、单元测试示例、集成测试模式和生产环境监控技术。


绿色计算

仅在由可再生能源供电的数据中心运行 cron 触发器。

启用绿色计算

通过控制面板:

  1. 前往 Workers & Pages
  2. 在 Account details 部分找到 Compute Setting
  3. 点击 Change
  4. 选择 Green Compute
  5. 点击 Confirm

适用范围:

  • 账户中的所有 cron 触发器
  • 减少碳足迹
  • 不产生额外费用
  • 可能会导致某些地区略有延迟

工作原理:

  • Cloudflare 将 cron 执行路由至由绿色能源供电的数据中心
  • 使用可再生能源:风能、太阳能、水力发电
  • 通过购电协议(PPAs)和可再生能源证书(RECs)进行认证

已知问题预防

此技能可预防 6 个已记录的问题:

问题 #1:Cron 更改未生效

错误: wrangler.jsonc 中的 cron 触发器已更新,但未执行

来源: Cloudflare 文档 - Cron Triggers

发生原因:

  • cron 触发器的更改最多需要 15 分钟才能在全球范围内生效
  • Cloudflare 网络需要时间更新边缘节点
  • 不像常规部署那样即时生效

预防方法:

  • 部署后等待 15 分钟,再确认触发器是否执行
  • 检查控制面板:Workers & Pages > [Worker] > Cron Triggers
  • 仅更改触发器时,使用 wrangler triggers deploy
# If you only changed triggers (not code), use:
bunx wrangler triggers deploy

# Wait 15 minutes, then verify in dashboard

问题 #2:处理程序未导出

错误: Handler does not export a 'scheduled' method

来源: 常见部署错误

发生原因:

  • 处理程序的名称并非准确的 scheduled
  • 处理程序未在默认导出对象中导出
  • 使用了 Service Worker 格式,而非 ES modules

预防方法:

// ❌ Wrong: Incorrect handler name
export default {
  async scheduledHandler(controller, env, ctx) { }
};

// ❌ Wrong: Not in default export
export async function scheduled(controller, env, ctx) { }

// ✅ Correct: Named 'scheduled' in default export
export default {
  async scheduled(controller, env, ctx) { }
};

问题 #3:UTC 时区混淆

错误: Cron 在错误的时间运行

来源: 用户预期与实际情况不符

发生原因:

  • 所有 cron 触发器都只按 UTC 时间运行
  • 无法进行时区转换
  • 用户预期使用本地时区

预防措施:

手动将本地时间转换为 UTC:

// Want to run at 9am PST (UTC-8)?
// 9am PST = 5pm UTC (17:00)
{
  "triggers": {
    "crons": ["0 17 * * *"]  // 9am PST = 5pm UTC
  }
}

// Want to run at 6pm EST (UTC-5)?
// 6pm EST = 11pm UTC (23:00)
{
  "triggers": {
    "crons": ["0 23 * * *"]  // 6pm EST = 11pm UTC
  }
}

// Remember: DST changes affect conversion!
// PST is UTC-8, PDT is UTC-7

工具:


问题 #4:Cron 表达式无效

错误: Cron 未执行,也没有显示错误

来源: 验证失败但未提示

发生原因:

  • 无效的 cron 语法会静默失败
  • 部署时会进行验证,但可能不易察觉
  • 常见错误:字段顺序错误、范围无效

预防措施:

# ❌ Wrong: Too many fields (6 fields instead of 5)
"crons": ["0 0 * * * *"]  # Has seconds field - not supported

# ❌ Wrong: Invalid minute range
"crons": ["65 * * * *"]  # Minute must be 0-59

# ❌ Wrong: Invalid day of week
"crons": ["0 0 * * 7"]  # Day of week is 0-6 (use 0 for Sunday)

# ✅ Correct: 5 fields, valid ranges
"crons": ["0 0 * * 0"]  # Sunday at midnight UTC

验证:

  • 使用 Crontab Guru 验证表达式
  • 检查 wrangler deploy 的输出中是否有错误
  • 使用 --test-scheduled 在本地测试

问题 #5:缺少 ES 模块格式

错误: Worker must use ES modules format

来源: 旧版 Service Worker 格式

发生原因:

  • 定时处理程序需要使用 ES 模块格式
  • 不支持旧版 Service Worker 格式
  • 代码库中混用了不同格式

预防措施:

// ❌ Wrong: Service Worker format
addEventListener('scheduled', (event) => {
  event.waitUntil(handleScheduled(event));
});

// ✅ Correct: ES modules format
export default {
  async scheduled(controller, env, ctx) {
    await handleScheduled(controller, env, ctx);
  },
};

问题 #6:超出 CPU 时间限制

错误: CPU time limit exceeded

来源: 长时间运行的定时任务

发生原因:

  • 默认 CPU 限制:30 秒
  • 长时间运行的任务会超出限制
  • 不会自动延长超时时间

预防措施:

选项 1:在 wrangler.jsonc 中提高 CPU 限制

{
  "limits": {
    "cpu_ms": 300000  // 5 minutes (max for Standard plan)
  }
}

选项 2:对长时间运行的任务使用 Workflows

// Instead of long task in cron:
export default {
  async scheduled(controller, env, ctx) {
    // Trigger Workflow that can run for hours
    await env.MY_WORKFLOW.create({
      params: { task: 'long-running-job' },
    });
  },
};

选项 3:拆分为更小的任务块

export default {
  async scheduled(controller, env, ctx) {
    // Process in batches
    const batch = await getNextBatch(env.DB);

    for (const item of batch) {
      await processItem(item);
    }

    // If more work, send to Queue for next batch
    const hasMore = await hasMoreWork(env.DB);
    if (hasMore) {
      await env.MY_QUEUE.send({ type: 'continue-processing' });
    }
  },
};

务必做到 ✅

  1. 使用准确的处理程序名称 - 必须是 scheduled,不能是 scheduledHandler 或其变体
  2. 使用 ES 模块格式 - 在默认对象中导出,不要使用 addEventListener
  3. 转换为 UTC - 所有 cron 时间均为 UTC,请从本地时区转换
  4. 等待 15 分钟 - Cron 更改最多需要 15 分钟才能生效
  5. 先在本地测试 - 使用 wrangler dev --test-scheduled
  6. 验证 cron 语法 - 使用 Crontab Guru
  7. 妥善处理错误 - 记录日志、发送警报,并可选择重新抛出错误
  8. 使用 ctx.waitUntil() - 用于非关键的异步操作
  9. 考虑使用 Workflows - 适用于 CPU 时间超过 30 秒的任务
  10. 监控执行情况 - 定期检查仪表板日志

切勿这样做 ❌

  1. 切勿假定使用本地时区 - 所有 cron 均按 UTC 运行
  2. 切勿使用 6 字段 cron 表达式 - Cloudflare 使用 5 字段格式(不含秒)
  3. 切勿指望立即生效 - 更改最多需要 15 分钟
  4. 切勿使用 Service Worker 格式 - 必须使用 ES 模块格式
  5. 切勿忘记错误处理 - 未捕获的错误会静默失败
  6. 切勿在未提高限制时运行 CPU 密集型任务 - 默认限制为 30s
  7. 星期字段切勿使用 7 - 星期日使用 0(范围仅为 0-6)
  8. 切勿未经测试就部署 - 务必先使用 --test-scheduled 测试
  9. 切勿忽略执行日志 - 仪表板会显示过去的失败记录
  10. 切勿为测试硬编码计划 - 使用特定于环境的配置

常见用例

加载 references/common-patterns.md,查看 10 种真实世界的 cron 模式,包括数据库清理、API 数据收集、每日报告生成、缓存预热、监控与运行状况检查、数据同步、自动备份、站点地图生成、Webhook 处理和定时通知。


TypeScript 类型

// Scheduled event controller
interface ScheduledController {
  readonly cron: string;
  readonly type: string;
  readonly scheduledTime: number;
}

// Execution context
interface ExecutionContext {
  waitUntil(promise: Promise<any>): void;
  passThroughOnException(): void;
}

// Scheduled handler
export default {
  async scheduled(
    controller: ScheduledController,
    env: Env,
    ctx: ExecutionContext
  ): Promise<void>;
}

限制与定价

限制
功能免费计划付费计划
每个 Worker 的 Cron 触发器数量3更多(请查阅文档)
每次执行的 CPU 时间10 ms(平均)30 秒(默认),5 min(最大)
墙上时钟时间30 秒15 分钟
内存128 MB128 MB
定价

Cron 触发器采用 Standard Workers 定价:

  • Workers Paid Plan:每月需支付 $5
  • 请求:每百万次请求 $0.30(超过 1,000 万次免费额度后)
  • CPU 时间:每百万 CPU-ms $0.02(超过 3,000 万次免费额度后)

每次 Cron 执行 = 1 次请求

示例:

  • Cron 每小时运行一次(每天 24 次)
  • 30 天 × 24 次执行 = 每月 720 次执行
  • 每次执行平均使用 50ms CPU 时间

费用:

  • 请求:720 次(远低于 1,000 万次免费额度)
  • CPU 时间:720 × 50ms = 36,000ms(低于 3,000 万次免费额度)
  • 总计:每月 $5(仅订阅费用)

高频示例:

  • Cron 每分钟运行一次(每天 1440 次)
  • 30 天 × 1440 次 = 每月 43,200 次执行
  • 仍在免费额度范围内
  • 总计:每月 $5

故障排查

问题:Cron 未执行

可能的原因:

  1. 更改尚未传播(等待 15 分钟)
  2. Cron 表达式无效
  3. 处理程序导出方式不正确
  4. Worker 尚未部署

解决方案:

# Re-deploy
bunx wrangler deploy

# Wait 15 minutes

# Check dashboard
# Workers & Pages > [Worker] > Cron Triggers

# Check logs
# Workers & Pages > [Worker] > Logs > Real-time Logs

问题:处理程序已执行,但失败

可能的原因:

  1. 处理程序中存在未捕获的错误
  2. 超出 CPU 时间限制
  3. 缺少环境绑定
  4. 网络超时

解决方案:

export default {
  async scheduled(controller, env, ctx) {
    try {
      await yourTask(env);
    } catch (error) {
      // Log detailed error
      console.error('Handler failed:', {
        error: error.message,
        stack: error.stack,
        cron: controller.cron,
        time: new Date(controller.scheduledTime),
      });

      // Send alert
      ctx.waitUntil(sendAlert(error));

      // Re-throw to mark as failed
      throw error;
    }
  },
};

在控制面板中查看日志,了解错误详情。


问题:执行时间不正确

原因: 混淆了 UTC 与本地时区

解决方案:

将所需的本地时间转换为 UTC:

// Want 9am PST (UTC-8)?
// 9am PST = 5pm UTC (17:00)

{
  "triggers": {
    "crons": ["0 17 * * *"]
  }
}

工具:


问题:本地测试无法正常运行

可能的原因:

  1. 缺少 --test-scheduled 标志
  2. 端点错误(应为 /__scheduled)
  3. Python Worker(请使用 /cdn-cgi/handler/scheduled)

解决方案:

# Correct: Start with flag
bunx wrangler dev --test-scheduled

# In another terminal
curl "http://localhost:8787/__scheduled?cron=0+*+*+*+*"

生产环境检查清单

将 Cron 触发器部署到生产环境之前:

  • 已在 Crontab Guru 上验证 Cron 表达式
  • 默认导出中的处理程序名称准确为 scheduled
  • 使用 ES modules 格式(而非 Service Worker)
  • 已将本地时区转换为 UTC
  • 已通过日志记录实现错误处理
  • 已为故障配置警报
  • 如有需要,已提高 CPU 限制(limits.cpu_ms)
  • 已测试环境绑定
  • 已使用 --test-scheduled 在本地测试
  • 已在预发布环境中测试部署
  • 部署后已等待 15 分钟以完成传播
  • 已在控制面板日志中确认执行情况
  • 已配置监控和警报
  • 已更新包含调度详情的文档

相关文档


最后更新:2025-10-23 版本:1.0.0 维护者:Claude Skills Maintainers | [email protected]

评论

支持 Markdown