1927 字
10 分钟
Cloudflare Workers 开发者指南

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.tomlbindings(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 支持 WebSocketPairReadableStream,使用 c.fwd 或 Hono/itty-router 处理更方便。注意 compatibility_flags 需要开启 web_socket_compression

与框架结合#

  • Hono:轻量 TypeScript 框架,npm create hono@latest -- --cloudflare-workers
  • Astro SSR:通过 @astrojs/cloudflare adapter。
  • 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.tomltriggers.crons 已配置,且 Worker 部署在支持 Cron 的计划(Free 计划每天 3 次)

发布流程建议#

  1. 使用 GitHub Actions / Cloudflare Pages 集成自动部署。
  2. PR 阶段运行 wrangler deploy --dry-run 快速验证编译。
  3. 使用 wrangler deploy --env staging 发布到预发,结合 Zero Trust 限制访问。
  4. 通过 wrangler tail 或 Logpush 观察 200/500 比例。
  5. 升级 compatibility_date 前在 staging 测试,确保向后兼容。

进一步阅读#

掌握以上内容后,可以快速利用 Cloudflare Workers 构建全球加速、成本可控的边缘应用,从个人项目到企业级服务都能覆盖。基于模块化、标准化的 API,开发体验与浏览器端极为相似,入门门槛远低于传统 Serverless 平台。

Cloudflare Workers 开发者指南
https://bangwu.top/posts/cloudflare-worker/
作者
棒无
发布于
2025-05-24
许可协议
CC BY-NC-SA 4.0