Workers 是什么
Cloudflare Workers 是运行在 Cloudflare 全球 310+ 边缘节点上的无服务器计算平台。它兼容 Web 标准(Fetch API、Service Worker 语法),支持亚毫秒级冷启动,非常适合:
- 前端 BFF、API 网关、A/B 测试;
- 请求重写、缓存、鉴权;
- 静态/动态渲染(SSR)、后台任务(Cron Triggers、Queues);
- 结合 KV、D1、R2 等产品构建完整的全栈应用。
Workers 采用“事件驱动 + Module Worker”模式,开发者只需导出 fetch/scheduled/queue 等 handler 即可。
基础架构概览
- Worker:核心运行单元,处理 HTTP、计划任务、队列消息。
- KV:全球分发的键值存储,读多写少场景。
- Durable Objects:具备状态的一致性 Actor,用于实时协作、计数、聊天室。
- R2:兼容 S3 的对象存储,免出口费。
- D1:托管 SQLite 数据库。
- Queues / Cron Triggers:后台任务、消息队列。
- Zero Trust / Turnstile:安全防护、验证码。
Workers 原生支持 TypeScript、ES Modules、npm 包(要求 ESM/边缘兼容),生态工具以 Wrangler CLI 为中心。
准备开发环境
安装 Wrangler
npm install -g wrangler
# 或者使用 pnpm/yarn:pnpm add -g wrangler
wrangler login # 打开浏览器授权
登陆后 Wrangler 会保存 API Token 到 ~/.wrangler/config/default.toml。
初始化项目
npm create cloudflare@latest my-worker
cd my-worker
npm install
CLI 会询问运行时(JavaScript/TypeScript)、模板(Hello World、Hono、Queues 等)、是否开启测试框架 Vitest。生成的目录结构通常包含:
src/index.ts:Worker 入口(Module Worker)。wrangler.toml:项目配置。package.json:依赖与脚本。tsconfig.json:TS 编译配置。
编写你的第一个 Worker
src/index.ts 示例:
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
const { pathname } = new URL(request.url);
if (pathname === '/hello') {
return new Response(JSON.stringify({ message: 'Hello from Workers' }), {
headers: { 'Content-Type': 'application/json' },
});
}
return new Response('Not Found', { status: 404 });
},
};
Env 接口代表 wrangler.toml 中 bindings(KV、R2、Secrets 等),可通过 types 字段指定。
wrangler.toml 配置
name = "my-worker"
main = "src/index.ts"
compatibility_date = "2024-11-01"
compatibility_flags = ["web_socket_compression"]
logpush = true
[vars]
API_BASE = "https://api.example.com"
[[kv_namespaces]]
binding = "CACHE"
id = "xxxxxx..."
[[d1_databases]]
binding = "DB"
database_name = "my-db"
database_id = "yyyyyy..."
[triggers]
crons = ["0 */1 * * *"] # 每小时运行
注意事项:
compatibility_date决定运行时 API 行为,建议定期升级。vars会作为环境变量注入env。- 绑定(binding)名称是代码里访问的名称。
- 对于
development环境可使用[env.dev]覆盖配置,实现多环境部署。
本地开发与调试
wrangler dev
wrangler dev
# 或指定端口 / 远程模式
wrangler dev --port 8787 --remote
- 默认使用 Miniflare 在本地模拟,支持热重载。
--remote与--live-reload会将请求发送到最近的 Cloudflare 边缘节点,适合测试与第三方服务交互。--inspect可开启 Chrome DevTools 调试。
请求测试
curl http://127.0.0.1:8787/hello
本地环境无法访问生产 KV/R2,Wrangler 会提供模拟器。若需要真实数据,可在 wrangler dev --remote 时指定 --persist 或在 wrangler.toml 中设置 kv_namespaces.preview_id。
日志查看
wrangler tail
# 或者过滤
wrangler tail --filters status=500
wrangler tail streaming 实时日志(默认 5 分钟),亦可导出到 Logpush(存储到 R2、Splunk、Datadog 等)。
部署
wrangler deploy
# 指定环境
wrangler deploy --env production
成功后 CLI 会返回访问 URL,以及 Worker KV 等绑定结果。生产日志可通过 Cloudflare Dashboard > Workers > Your Worker > Logs 查看。
绑定 Cloudflare 产品
KV(键值存储)
在 Dashboard 创建 KV namespace,复制 Namespace ID 填入 wrangler.toml:
[[kv_namespaces]]
binding = "CACHE"
id = "xxxxxxxx"
preview_id = "yyyyyyyy" # 可选,用于 dev 环境
使用示例:
await env.CACHE.put('key', 'value', { expirationTtl: 3600 });
const result = await env.CACHE.get('key');
KV 写入最终一致、读多写少;写操作可一次性 put/delete,不要当事务数据库使用。
Durable Objects
[[durable_objects.bindings]]
name = "ROOM"
class_name = "RoomDO"
export class RoomDO {
state: DurableObjectState;
constructor(state: DurableObjectState, env: Env) {
this.state = state;
}
async fetch(request: Request) {
const messages = (await this.state.storage.get<string[]>('messages')) ?? [];
return new Response(JSON.stringify({ messages }), {
headers: { 'Content-Type': 'application/json' },
});
}
}
在 Worker 中使用:
const id = env.ROOM.idFromName('general');
const stub = env.ROOM.get(id);
const res = await stub.fetch(request);
D1(数据库)
[[d1_databases]]
binding = "DB"
database_name = "app-db"
database_id = "abc123"
const { results } = await env.DB.prepare('SELECT * FROM todos WHERE done = ?').bind(false).all();
配合 drizzle-orm, kysely 等 ORM 使用时,需确保运行时兼容(一般使用 drizzle-orm/d1 driver)。
R2(对象存储)
[[r2_buckets]]
binding = "ASSETS"
bucket_name = "my-assets"
await env.ASSETS.put('images/logo.png', fileReadableStream);
const object = await env.ASSETS.get('images/logo.png');
return new Response(object?.body, { headers: object?.httpMetadata });
Queues
[[queues.producers]]
queue = "task-queue"
binding = "TASK_QUEUE"
[[queues.consumers]]
queue = "task-queue"
max_batch_size = 1
max_batch_timeout = 30
Producer:
await env.TASK_QUEUE.send({ type: 'email', payload: { to: 'hi@example.com' } });
Consumer:
export default {
async queue(batch: MessageBatch<any>, env: Env, ctx: ExecutionContext) {
for (const msg of batch.messages) {
// 处理任务
msg.ack();
}
},
};
Secrets 与环境变量
普通变量
wrangler.toml 中 [vars] 会以字符串注入。适合非敏感配置:
[vars]
API_BASE = "https://api.example.com"
代码中:env.API_BASE。
Secrets
敏感信息使用 wrangler secret put:
wrangler secret put GITHUB_TOKEN
Secrets 默认仅存在于特定环境,请分别为 preview/production 设置。删除:wrangler secret delete.
多环境管理
[env.preview]
vars = { API_BASE = "https://staging.example.com" }
[env.production]
vars = { API_BASE = "https://api.example.com" }
部署时:wrangler deploy --env production。
常见事件与示例
HTTP Fetch
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext) {
ctx.waitUntil(env.ANALYTICS.write({ path: new URL(request.url).pathname }));
return new Response('OK');
},
};
Cron Trigger
export default {
async scheduled(event: ScheduledEvent, env: Env, ctx: ExecutionContext) {
await env.REPORT_QUEUE.send({ at: event.scheduledTime });
},
};
在 Dashboard 或 wrangler.toml 的 [triggers] 中配置 Cron 表达式。
WebSocket / SSE
Workers 支持 WebSocketPair 与 ReadableStream,使用 c.fwd 或 Hono/itty-router 处理更方便。注意 compatibility_flags 需要开启 web_socket_compression。
与框架结合
- Hono:轻量 TypeScript 框架,
npm create hono@latest -- --cloudflare-workers。 - Astro SSR:通过
@astrojs/cloudflareadapter。 - Next.js Middleware / Pages:Workers 可作为自定义服务器或中间层。
- Remix:官方支持
remix-cloudflare.
示例(Hono):
import { Hono } from 'hono';
import { zValidator } from '@hono/zod-validator';
import { z } from 'zod';
type Bindings = {
DB: D1Database;
};
const app = new Hono<{ Bindings: Bindings }>();
app.get('/todos', async (c) => {
const { results } = await c.env.DB.prepare('SELECT * FROM todos').all();
return c.json(results);
});
app.post(
'/todos',
zValidator('json', z.object({ title: z.string().min(1) })),
async (c) => {
const { title } = c.req.valid('json');
await c.env.DB.prepare('INSERT INTO todos (title) VALUES (?)').bind(title).run();
return c.json({ message: 'created' }, 201);
}
);
export default app;
调试与 Observability
wrangler tail:实时日志。wrangler dev --inspect:Chrome DevTools。- Workers Metrics:Dashboard 提供请求量、CPU 时间、错误率。
- Workers Trace Events:可启用 HTTP 请求追踪(Beta)。
- Logpush:将日志推送到 R2、S3、Datadog。
- Workers Analytics Engine:结构化日志,可通过 SQL 查询。
推荐在代码中引入请求 ID:
const requestId = crypto.randomUUID();
console.log('request start', requestId);
并统一使用 ctx.waitUntil 上报异步日志。
性能优化建议
保持函数纯粹,避免阻塞操作;长任务使用 Queues。
复用
fetch请求:避免多次调用同一 API,利用Promise.all。合理使用
Cache API:const cache = caches.default; const cacheKey = new Request(request.url, request); let response = await cache.match(cacheKey); if (!response) { response = await fetch(request); ctx.waitUntil(cache.put(cacheKey, response.clone())); } return response;静态资源放 R2 + CDN,Workers 做鉴权与签名。
如果依赖第三方 npm 包,确认其兼容 Web 平台(无 Node-specific API)。
安全与合规
- 使用
wrangler secret管理敏感信息。 - 与 Cloudflare Zero Trust 集成,限制访问来源。
- 使用 Turnstile 抵御机器人。
- 需要 CORS 时手动设置
Access-Control-Allow-Origin,并关注OPTIONS预检。 - 对于用户数据,结合 DLP/日志脱敏策略。
常见问题排查
| 问题 | 排查思路 |
|---|---|
| 522/525 错误 | 检查 Worker 超时(CPU 时间超过限制)、上游服务不可达 |
| 本地 dev 行为与生产不一致 | 使用 wrangler dev --remote,或确认 compatibility_date 一致 |
| 未找到绑定 | 确认 wrangler.toml 中 binding 名称与代码一致,部署后刷新 Dashboard |
| npm 包不兼容 | 优先选用 ESM、无 Node API 的库;或通过 workerd polyfill |
| Request body 重复读取失败 | 使用 request.clone() 复用流 |
| Cron 不触发 | 确认 wrangler.toml 中 triggers.crons 已配置,且 Worker 部署在支持 Cron 的计划(Free 计划每天 3 次) |
发布流程建议
- 使用 GitHub Actions / Cloudflare Pages 集成自动部署。
- PR 阶段运行
wrangler deploy --dry-run快速验证编译。 - 使用
wrangler deploy --env staging发布到预发,结合 Zero Trust 限制访问。 - 通过
wrangler tail或 Logpush 观察 200/500 比例。 - 升级
compatibility_date前在 staging 测试,确保向后兼容。
进一步阅读
- Cloudflare Workers 官方文档
- wrangler CLI 指南
- Workers Templates
- Durable Objects Cookbook
- Cloudflare Queues
- Workers Observability
- Workerd Runtime 源码
掌握以上内容后,可以快速利用 Cloudflare Workers 构建全球加速、成本可控的边缘应用,从个人项目到企业级服务都能覆盖。基于模块化、标准化的 API,开发体验与浏览器端极为相似,入门门槛远低于传统 Serverless 平台。


