跳转至

Cloudflare Workers 边缘计算

一句话概述:Cloudflare Workers 是在全球 300+ 个边缘节点运行的无服务器平台,代码部署后在离用户最近的节点执行,延迟极低,免费额度每天 10 万次请求。

核心知识点

概念白话解释
边缘计算代码不在一个中心机房跑,而是分散到全球各地,离用户近
V8 IsolatesWorkers 用的运行时,比容器更轻量,冷启动几乎为零
WranglerWorkers 的 CLI 开发工具
KV键值存储,适合读多写少的数据
D1Cloudflare 的 SQLite 数据库
R2对象存储(类似 S3),无出口流量费
Durable Objects有状态的边缘计算,适合实时协作、WebSocket

安装配置

# 安装 Wrangler CLI
npm install -g wrangler  # 全局安装

# 登录 Cloudflare
wrangler login  # 打开浏览器授权

# 创建项目
npm create cloudflare@latest my-worker  # 交互式创建项目
cd my-worker

配置文件

# wrangler.toml
name = "my-worker"  # Worker 名称
main = "src/index.ts"  # 入口文件
compatibility_date = "2025-01-01"  # 兼容日期

# KV 命名空间绑定
[[kv_namespaces]]
binding = "MY_KV"  # 代码中的变量名
id = "abc123"  # KV 命名空间 ID

# D1 数据库绑定
[[d1_databases]]
binding = "DB"
database_name = "my-database"
database_id = "xxx-xxx"

# R2 存储绑定
[[r2_buckets]]
binding = "MY_BUCKET"
bucket_name = "my-files"

# 环境变量
[vars]
API_KEY = "your-api-key"

基本使用

Hello World

// src/index.ts
export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const url = new URL(request.url)  // 解析请求 URL

    if (url.pathname === '/hello') {
      return new Response('你好,世界!', {  // 返回响应
        headers: { 'Content-Type': 'text/plain; charset=utf-8' },
      })
    }

    if (url.pathname === '/api/user') {
      const data = { id: 1, name: '张三' }  // 返回 JSON
      return Response.json(data)
    }

    return new Response('Not Found', { status: 404 })  // 404
  },
}

路由处理

// src/index.ts - 简单路由
export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const url = new URL(request.url)
    const { pathname } = url

    // GET 请求
    if (request.method === 'GET' && pathname === '/api/users') {
      return Response.json([{ id: 1, name: '张三' }])
    }

    // POST 请求
    if (request.method === 'POST' && pathname === '/api/users') {
      const body = await request.json() as { name: string }  // 解析 JSON 请求体
      return Response.json({ id: Date.now(), name: body.name }, { status: 201 })
    }

    // 查询参数
    if (pathname === '/search') {
      const q = url.searchParams.get('q') || ''  // 获取 ?q=xxx
      return Response.json({ query: q, results: [] })
    }

    return new Response('Not Found', { status: 404 })
  },
}

本地开发与部署

wrangler dev  # 本地开发服务器(http://localhost:8787)
wrangler deploy  # 部署到 Cloudflare
wrangler tail  # 实时查看日志

高级用法

KV 存储

wrangler kv namespace create MY_KV  # 创建 KV 命名空间
export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    // 写入 KV
    await env.MY_KV.put('user:1', JSON.stringify({ name: '张三' }))  // 存数据
    await env.MY_KV.put('session:abc', 'data', { expirationTtl: 3600 })  // 1小时过期

    // 读取 KV
    const user = await env.MY_KV.get('user:1', 'json')  // 读取并解析 JSON
    return Response.json(user)
  },
}

D1 数据库

wrangler d1 create my-database  # 创建 D1 数据库
wrangler d1 execute my-database --command "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)"  # 建表
export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    // 查询
    const { results } = await env.DB.prepare(
      'SELECT * FROM users WHERE id = ?'  // 参数化查询(防注入)
    ).bind(1).all()  // 绑定参数并执行

    // 插入
    await env.DB.prepare(
      'INSERT INTO users (name) VALUES (?)'
    ).bind('李四').run()

    return Response.json(results)
  },
}

定时任务(Cron)

# wrangler.toml
[triggers]
crons = ["0 * * * *"]  # 每小时执行
export default {
  async scheduled(event: ScheduledEvent, env: Env, ctx: ExecutionContext) {
    // 定时任务逻辑
    console.log('定时任务执行:', event.cron)
    ctx.waitUntil(cleanupOldData(env))  // 异步清理
  },
}

常见报错

报错信息原因解决方案
Error: Script too large代码包超过限制免费版 1MB,付费版 10MB,精简依赖
CPU time limit exceededCPU 时间超限免费版 10ms,优化逻辑或升级
KV namespace not foundKV 没绑定检查 wrangler.toml 中的绑定配置
Subrequest limit exceededfetch 调用次数超限免费版 50 次/请求,减少外部调用
No matching routes路由不匹配检查自定义域名或路由配置

速查表

# Wrangler CLI 命令
wrangler login             # 登录
wrangler dev               # 本地开发
wrangler deploy            # 部署
wrangler tail              # 实时日志
wrangler kv namespace create <名称>  # 创建 KV
wrangler d1 create <名称>  # 创建 D1 数据库
wrangler r2 bucket create <名称>  # 创建 R2 存储桶
wrangler secret put <名称>  # 设置密钥

# 免费额度(每天)
# 10 万次请求
# CPU 时间:10ms/请求
# 脚本大小:1MB
# KV:10 万次读 + 1000 次写
# D1:500 万行读 + 10 万行写
# R2:100 万次 A 类操作 + 1000 万次 B 类操作

参考:Cloudflare Workers 文档 | Wrangler | D1 文档