name: edge-computing-patterns description: 部署到边缘运行时(Cloudflare Workers、Vercel Edge、Deno Deploy),构建全球分布式、低延迟应用。掌握边缘中间件、流式处理和运行时约束,面向2025年及以后的边缘计算。 version: 1.0.0 author: AI Agent Hub tags: [edge, cloudflare, vercel, deno, serverless, 2025]
边缘计算模式
概述
边缘计算在全球范围内更靠近用户的位置运行代码,将延迟从秒级降低到毫秒级。本技能涵盖 Cloudflare Workers、Vercel Edge Functions 和 Deno Deploy 的模式,用于构建全球分布式应用。
何时使用此技能:
- 需要 <50ms 延迟的全球性应用
- 在边缘进行身份验证/授权
- A/B 测试和功能开关
- 地理路由和本地化
- API 速率限制和 DDoS 防护
- 转换响应(图像优化、HTML 重写)
平台对比
| 特性 | Cloudflare Workers | Vercel Edge | Deno Deploy |
|---|---|---|---|
| 冷启动 | <1ms | <10ms | <10ms |
| 位置 | 300+ | 100+ | 35+ |
| 运行时 | V8 Isolates | V8 Isolates | Deno |
| 最大时长 | 30秒(付费:无限制) | 25秒 | 50毫秒-5分钟 |
| 免费额度 | 10万次请求/天 | 10万次请求/月 | 10万次请求/月 |
Cloudflare Workers
// worker.ts
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url)
// 地理路由
const country = request.cf?.country || 'US'
if (url.pathname === '/api/hello') {
return new Response(JSON.stringify({
message: `Hello from ${country}!`
}), {
headers: { 'Content-Type': 'application/json' }
})
}
// 缓存 API
const cache = caches.default
let response = await cache.match(request)
if (!response) {
response = await fetch(request)
// 缓存1小时
response = new Response(response.body, response)
response.headers.set('Cache-Control', 'max-age=3600')
await cache.put(request, response.clone())
}
return response
}
}
// 用于有状态边缘的 Durable Objects
export class Counter {
private state: DurableObjectState
private count = 0
constructor(state: DurableObjectState) {
this.state = state
}
async fetch(request: Request) {
const url = new URL(request.url)
if (url.pathname === '/increment') {
this.count++
await this.state.storage.put('count', this.count)
}
return new Response(JSON.stringify({ count: this.count }))
}
}
Vercel Edge Functions
// middleware.ts (边缘中间件)
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
// A/B 测试
const bucket = Math.random() < 0.5 ? 'a' : 'b'
const url = request.nextUrl.clone()
url.searchParams.set('bucket', bucket)
// 地理位置
const country = request.geo?.country || 'US'
const response = NextResponse.rewrite(url)
response.cookies.set('bucket', bucket)
response.headers.set('X-Country', country)
return response
}
export const config = {
matcher: '/experiment/:path*'
}
// 边缘 API 路由
export const runtime = 'edge'
export async function GET(request: Request) {
return new Response(JSON.stringify({
timestamp: Date.now(),
region: process.env.VERCEL_REGION
}))
}
边缘运行时约束
✅ 可用:
fetch,Request,Response,HeadersURL,URLSearchParamsTextEncoder,TextDecoderReadableStream,WritableStreamcrypto,SubtleCrypto- Web APIs (atob, btoa, setTimeout, 等)
❌ 不可用:
- Node.js APIs (
fs,path,child_process) - 原生模块
- 某些 npm 包
- 文件系统访问
常见模式
边缘身份验证
import { verify } from '@tsndr/cloudflare-worker-jwt'
export default {
async fetch(request: Request, env: Env) {
const token = request.headers.get('Authorization')?.replace('Bearer ', '')
if (!token) {
return new Response('未授权', { status: 401 })
}
const isValid = await verify(token, env.JWT_SECRET)
if (!isValid) {
return new Response('令牌无效', { status: 403 })
}
// 继续处理已认证的请求
return fetch(request)
}
}
速率限制
export default {
async fetch(request: Request, env: Env) {
const ip = request.headers.get('CF-Connecting-IP')
const key = `ratelimit:${ip}`
// 使用 KV 进行速率限制
const count = await env.KV.get(key)
const currentCount = count ? parseInt(count) : 0
if (currentCount >= 100) {
return new Response('超出速率限制', { status: 429 })
}
await env.KV.put(key, (currentCount + 1).toString(), {
expirationTtl: 60 // 1 分钟
})
return fetch(request)
}
}
边缘缓存
async function handleRequest(request: Request) {
const cache = caches.default
const cacheKey = new Request(request.url, request)
// 首先尝试缓存
let response = await cache.match(cacheKey)
if (!response) {
// 从源站获取
response = await fetch(request)
// 缓存成功的响应
if (response.status === 200) {
response = new Response(response.body, response)
response.headers.set('Cache-Control', 'max-age=3600')
await cache.put(cacheKey, response.clone())
}
}
return response
}
最佳实践
- ✅ 保持包体积小 (<1MB)
- ✅ 对大响应使用流式处理
- ✅ 利用边缘缓存(KV、Durable Objects)
- ✅ 优雅地处理错误(边缘错误无法恢复)
- ✅ 测试冷启动和热启动
- ✅ 监控边缘函数性能
- ✅ 使用环境变量存储密钥
- ✅ 实现正确的 CORS 头