Cloudflare Workers 边缘计算¶
一句话概述:Cloudflare Workers 是在全球 300+ 个边缘节点运行的无服务器平台,代码部署后在离用户最近的节点执行,延迟极低,免费额度每天 10 万次请求。
核心知识点¶
| 概念 | 白话解释 |
|---|---|
| 边缘计算 | 代码不在一个中心机房跑,而是分散到全球各地,离用户近 |
| V8 Isolates | Workers 用的运行时,比容器更轻量,冷启动几乎为零 |
| Wrangler | Workers 的 CLI 开发工具 |
| KV | 键值存储,适合读多写少的数据 |
| D1 | Cloudflare 的 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 存储¶
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)¶
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 exceeded | CPU 时间超限 | 免费版 10ms,优化逻辑或升级 |
KV namespace not found | KV 没绑定 | 检查 wrangler.toml 中的绑定配置 |
Subrequest limit exceeded | fetch 调用次数超限 | 免费版 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 文档