Cloudflare Workers 脚本执行超时报错 10s 限制怎么优化代码

文章导读
遇到 10s 超时报错,最直接的优化方向是减少同步等待时间,把耗时操作改为异步或移到后台任务,同时检查是否触发了更严格的 CPU 时间限制。
📋 目录
  1. 快速处理思路
  2. 为什么会这样
  3. 分步处理
  4. 怎么验证是否生效
A A

遇到 10s 超时报错,最直接的优化方向是减少同步等待时间,把耗时操作改为异步或移到后台任务,同时检查是否触发了更严格的 CPU 时间限制。

先说结论:10s 通常是墙钟时间上限,但实际瓶颈常在 CPU 时间,优化需区分等待耗时与计算耗时。

  • 先定位:查看日志区分是外部请求慢还是代码计算慢。
  • 先做:将非关键逻辑改为异步等待,或启用缓存减少重复请求。
  • 再验证:在后台观察 CPU 耗时指标是否下降,确认不再触发超时。

快速处理思路

这类问题不适合用单条命令解决,核心在于代码逻辑调整。你可以先检查代码中所有的 await fetch() 或同步循环,把不需要立即返回结果的操作包裹在 event.waitUntil() 中,确保主请求链路只处理必要逻辑。如果涉及大量数据处理,考虑分片处理或改用 Cloudflare Queues 异步消费。

为什么会这样

Cloudflare Workers 有两个关键的时间限制概念。一个是墙钟时间(Wall-clock Time),即从请求开始到响应结束的总时长,标准计划通常限制在 10s 左右;另一个是 CPU 时间,即脚本实际占用处理器运行的时间。免费计划与付费计划的 CPU 时间配额不同(具体数值请以官方最新文档为准)。

很多开发者误以为只要总时长不超过 10s 就不会报错,但实际上如果代码中有密集计算,哪怕总耗时只有 1s,也可能因为 CPU 时间超限而终止。反之,如果主要是等待外部 API 响应,虽然不消耗太多 CPU,但总时长超过 10s 同样会触发超时错误。

分步处理

1. 配置兼容性日期
确保 wrangler.toml 中设置了较新的兼容性日期,以支持 AbortSignal.timeout 等新特性:

Cloudflare Workers 脚本执行超时报错 10s 限制怎么优化代码
# wrangler.toml
compatibility_date = "2022-11-30"
name = "my-worker"
main = "src/index.js"

2. 检查日志定位瓶颈
使用 Wrangler CLI 实时查看日志,过滤错误信息:

wrangler tail `--log-level` error

登录 Cloudflare dashboard,进入 Workers 页面的“日志”或“分析”标签。查看报错请求的详细追踪,确认是 script exceeded CPU limit 还是 execution timed out。前者需要优化算法,后者需要减少等待。

3. 优化外部请求与完整代码示例
如果是因为等待第三方 API 超时,推荐使用 AbortSignal.timeout 替代传统的 setTimeout 组合,兼容性更好。以下是包含超时控制与异步任务的完整 addEventListener 示例:

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
  // 设置 5 秒超时信号
  const signal = AbortSignal.timeout(5000)
  
  try {
    const res = await fetch('https://api.example.com/data', { signal })
    const data = await res.json()
    
    // 非关键任务异步化,不阻塞响应
    event.waitUntil(logAnalytics(data))
    
    return new Response(JSON.stringify(data), {
      headers: { 'content-type': 'application/json' }
    })
  } catch (e) {
    if (e.name === 'TimeoutError') {
      return new Response('Upstream timeout', { status: 504 })
    }
    throw e
  }
}

async function logAnalytics(data) {
  // 后台任务逻辑
  await fetch('https://analytics.example.com/log', {
    method: 'POST',
    body: JSON.stringify(data)
  })
}

4. 启用缓存
对于重复的请求,使用 Cache API 或 KV 存储结果。在发起网络请求前先查缓存,能显著降低墙钟时间和 CPU 消耗。

怎么验证是否生效

修改代码发布后,通过 curl 或浏览器多次触发请求。在 Workers 控制面板的“分析”页面,观察