Cloudflare Workers 是一个无服务器边缘计算平台,在全球 300+ 数据中心运行你的代码。与在特定区域运行的传统无服务器平台不同,Workers 在最靠近用户的边缘执行,提供亚毫秒级冷启动和超低延迟。
什么是 Cloudflare Workers?
Workers 是在 Cloudflare 边缘网络上运行的 JavaScript/TypeScript 函数。它们使用 V8 引擎在轻量级隔离环境中运行。
主要特性
- 亚毫秒级冷启动(V8 隔离,无容器启动)
- 0ms 调度:代码立即运行
- 全球部署:300+ 数据中心
- Web 标准 API:fetch、Request、Response、crypto
- 免费层:每天 100,000 请求
- 自动扩展:无需配置即可处理流量峰值
入门
使用 Wrangler CLI 在几分钟内创建和部署 Worker。
# Install Wrangler CLI
npm install -g wrangler
# Authenticate
wrangler login
# Create a new Worker project
npm create cloudflare@latest my-worker
cd my-worker
# Project structure
# my-worker/
# ├── src/
# │ └── index.ts # Worker entry point
# ├── wrangler.toml # Configuration
# ├── package.json
# └── tsconfig.json
# Local development
wrangler dev
# Deploy to production
wrangler deploy请求处理模式
Workers 使用 Web 标准 fetch 事件模型。
// src/index.ts - Basic Worker
export interface Env {
MY_KV: KVNamespace;
MY_DB: D1Database;
MY_BUCKET: R2Bucket;
}
export default {
async fetch(
request: Request,
env: Env,
ctx: ExecutionContext
): Promise<Response> {
const url = new URL(request.url);
// Simple routing
switch (url.pathname) {
case "/":
return new Response("Hello from the Edge!", {
headers: { "content-type": "text/plain" },
});
case "/api/data":
return Response.json({ time: Date.now(), edge: true });
case "/api/headers":
const headers: Record<string, string> = {};
request.headers.forEach((v, k) => (headers[k] = v));
return Response.json(headers);
default:
return new Response("Not Found", { status: 404 });
}
},
};URL 路由
Workers 没有内置路由器,但可以使用 URL 模式匹配或 Hono 框架实现路由。
// URL Pattern-based routing (built-in Web API)
const routes = [
{ pattern: new URLPattern({ pathname: "/api/users/:id" }), handler: getUser },
{ pattern: new URLPattern({ pathname: "/api/users" }), handler: listUsers },
{ pattern: new URLPattern({ pathname: "/api/posts/:slug" }), handler: getPost },
];
async function getUser(request: Request, params: Record<string, string>) {
return Response.json({ id: params.id, name: "Alice" });
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = request.url;
for (const route of routes) {
const match = route.pattern.exec(url);
if (match) {
return route.handler(request, match.pathname.groups);
}
}
return new Response("Not Found", { status: 404 });
},
};KV:键值存储
Workers KV 是全球分布的最终一致性键值存储,优化用于高读低写工作负载。
// wrangler.toml
// [[kv_namespaces]]
// binding = "CACHE"
// id = "abc123"
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url);
const cacheKey = `page:${url.pathname}`;
// Read from KV (returns null if not found)
const cached = await env.CACHE.get(cacheKey);
if (cached) {
return new Response(cached, {
headers: { "x-cache": "hit", "content-type": "text/html" },
});
}
// Generate and cache the response
const html = `<html><body><h1>Page: ${url.pathname}</h1></body></html>`;
// Store in KV with 1 hour TTL
await env.CACHE.put(cacheKey, html, { expirationTtl: 3600 });
return new Response(html, {
headers: { "x-cache": "miss", "content-type": "text/html" },
});
},
};
// KV supports JSON, text, streams, and ArrayBuffer
// await env.CACHE.put("config", JSON.stringify(config));
// const config = await env.CACHE.get("config", "json");D1:边缘 SQLite
D1 是基于 SQLite 构建的无服务器 SQL 数据库,在边缘运行,提供低延迟数据库访问。
// Create D1 database
// wrangler d1 create my-database
// wrangler.toml
// [[d1_databases]]
// binding = "DB"
// database_name = "my-database"
// database_id = "xxx-xxx"
// schema.sql
// CREATE TABLE users (
// id INTEGER PRIMARY KEY AUTOINCREMENT,
// name TEXT NOT NULL,
// email TEXT UNIQUE NOT NULL,
// created_at TEXT DEFAULT (datetime('now'))
// );
// Apply schema: wrangler d1 execute my-database --file=schema.sql
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url);
if (url.pathname === "/api/users" && request.method === "GET") {
const { results } = await env.DB.prepare(
"SELECT * FROM users ORDER BY created_at DESC LIMIT 50"
).all();
return Response.json(results);
}
if (url.pathname === "/api/users" && request.method === "POST") {
const { name, email } = await request.json<{ name: string; email: string }>();
const result = await env.DB.prepare(
"INSERT INTO users (name, email) VALUES (?, ?)"
).bind(name, email).run();
return Response.json({ id: result.meta.last_row_id }, { status: 201 });
}
// Batch queries (single round trip)
if (url.pathname === "/api/stats") {
const [users, posts] = await env.DB.batch([
env.DB.prepare("SELECT COUNT(*) as count FROM users"),
env.DB.prepare("SELECT COUNT(*) as count FROM posts"),
]);
return Response.json({
users: users.results[0],
posts: posts.results[0],
});
}
return new Response("Not Found", { status: 404 });
},
};R2:对象存储
R2 是兼容 S3 的对象存储,零出口费用。适合存储图片、文件和静态资源。
// wrangler.toml
// [[r2_buckets]]
// binding = "STORAGE"
// bucket_name = "my-files"
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url);
const key = url.pathname.slice(1); // remove leading /
// Upload file
if (request.method === "PUT") {
await env.STORAGE.put(key, request.body, {
httpMetadata: {
contentType: request.headers.get("content-type") || "application/octet-stream",
},
});
return Response.json({ key, uploaded: true });
}
// Download file
if (request.method === "GET") {
const object = await env.STORAGE.get(key);
if (!object) return new Response("Not Found", { status: 404 });
return new Response(object.body, {
headers: {
"content-type": object.httpMetadata?.contentType || "application/octet-stream",
"etag": object.httpEtag,
},
});
}
// Delete file
if (request.method === "DELETE") {
await env.STORAGE.delete(key);
return Response.json({ key, deleted: true });
}
return new Response("Method not allowed", { status: 405 });
},
};使用 Hono 框架构建
Hono 是为边缘运行时设计的轻量级 Web 框架,提供路由、中间件和类型安全。
// Using Hono framework with Workers
import { Hono } from "hono";
import { cors } from "hono/cors";
import { jwt } from "hono/jwt";
type Bindings = { DB: D1Database; STORAGE: R2Bucket; JWT_SECRET: string };
const app = new Hono<{ Bindings: Bindings }>();
// Middleware
app.use("/api/*", cors());
app.use("/api/protected/*", async (c, next) => {
const jwtMiddleware = jwt({ secret: c.env.JWT_SECRET });
return jwtMiddleware(c, next);
});
// Routes
app.get("/", (c) => c.text("Hello Hono on Workers!"));
app.get("/api/users", async (c) => {
const { results } = await c.env.DB.prepare("SELECT * FROM users").all();
return c.json(results);
});
app.post("/api/users", async (c) => {
const { name, email } = await c.req.json();
const result = await c.env.DB.prepare(
"INSERT INTO users (name, email) VALUES (?, ?)"
).bind(name, email).run();
return c.json({ id: result.meta.last_row_id }, 201);
});
app.get("/api/protected/me", (c) => {
const payload = c.get("jwtPayload");
return c.json({ user: payload });
});
export default app;性能最佳实践
- 使用 Cache API 在边缘缓存响应
- 在请求内缓存 KV 值以减少读取
- 对大型负载使用流式响应
- 保持 Worker 脚本小巧以减少冷启动时间
- 使用 D1 批量查询减少往返
- 使用 R2 存储静态资源
- 使用 Durable Objects 进行协调
- 为频繁调用源服务器的 Workers 启用智能放置
常见问题
Cloudflare Workers 费用多少?
免费层包括每天 100,000 请求。付费计划每月 5 美元,包括 1000 万请求、D1、KV 和 R2。
Workers 能取代传统后端吗?
对于许多应用可以。D1 用于数据库、R2 用于文件存储、KV 用于缓存、Durable Objects 用于有状态逻辑。
D1 已经准备好用于生产了吗?
D1 已正式可用且适合生产使用。支持完整 SQL、事务和自动读复制。
Workers 与 AWS Lambda 相比如何?
Workers 冷启动更快、距离用户更近、部署更简单。Lambda 支持更多语言和更长执行时间。
可以在 Workers 中使用 npm 包吗?
可以,使用 node_compat 标志。依赖 Node.js 特定 API 的包不工作,但 zod、hono 等流行包可以正常使用。