正在加载,请稍候…

Cloudflare Workers 边缘计算:构建全球分布式应用

使用 Cloudflare Workers 构建全球分布式应用:KV 存储、Durable Objects 实现一致性、R2 对象存储、队列消费者以及跨 300

Cloudflare Workers 边缘计算:构建全球分布式应用

Cloudflare Workers:边缘计算实践

Cloudflare Workers 在距离地球上每个用户毫秒级延迟的 300 多个数据中心内运行您的 JavaScript 或 WASM。与在单个区域运行的传统无服务器不同,Workers 在离请求用户最近的 PoP 中运行。

Workers 执行模型

Workers 使用 V8 隔离模型——而非容器或虚拟机。每个请求获得一个全新的 V8 上下文,启动时间约为 0ms(无冷启动)。请求之间的内存是隔离的。

// workers/api.js - 基本 Worker 结构
export default {
    async fetch(request, env, ctx) {
        const url = new URL(request.url);
        if (url.pathname.startsWith('/api/')) {
            return handleAPI(request, env);
        }
        const cached = await env.CACHE.get(url.pathname, 'arrayBuffer');
        if (cached) {
            return new Response(cached, {
                headers: { 'CF-Cache-Status': 'HIT', 'Cache-Control': 'public, max-age=3600' }
            });
        }
        const response = await fetch(request);
        ctx.waitUntil(
            env.CACHE.put(url.pathname, response.clone().body, { expirationTtl: 3600 })
        );
        return response;
    }
};

Cloudflare Workers 边缘计算:构建全球分布式应用 插图

KV:全局复制的键值存储

Workers KV 是最终一致性的(15 秒传播),非常适合配置、功能标志和缓存内容:

async function getFeatureFlags(env) {
    // KV 读取延迟约 1ms(从本地 PoP 缓存提供)
    return await env.CONFIG.get('feature-flags', 'json') ?? { newCheckout: false };
}

// 带元数据和 TTL 写入
await env.CONFIG.put('feature-flags', JSON.stringify({ newCheckout: true }), {
    expirationTtl: 3600,
    metadata: { updatedAt: Date.now() }
});

// 带前缀列出键
const keys = await env.CONFIG.list({ prefix: 'user:', limit: 100 });

Durable Objects:边缘的一致状态

Durable Objects 解决了 CAP 定理的挑战——每个对象在全局恰好一个位置运行,提供强一致性:

export class RateLimiter {
    constructor(state, env) { this.state = state; }

    async fetch(request) {
        const { userId, limit, windowSeconds } = await request.json();
        const now = Date.now();
        const windowStart = now - windowSeconds * 1000;
        const requests = await this.state.storage.get('requests') ?? [];
        const recent = requests.filter(ts => ts > windowStart);
        if (recent.length >= limit) {
            return Response.json({ allowed: false,
                retryAfter: Math.ceil((recent[0] + windowSeconds * 1000 - now) / 1000) });
        }
        recent.push(now);
        await this.state.storage.put('requests', recent);
        return Response.json({ allowed: true, remaining: limit - recent.length });
    }
}

export default {
    async fetch(request, env) {
        const userId = request.headers.get('X-User-Id');
        const id = env.RATE_LIMITER.idFromName(userId);
        const rateLimiter = env.RATE_LIMITER.get(id);
        const result = await rateLimiter.fetch(new Request('http://do/', {
            method: 'POST',
            body: JSON.stringify({ userId, limit: 100, windowSeconds: 60 })
        }));
        const { allowed, retryAfter } = await result.json();
        if (!allowed) return new Response('Rate limited', {
            status: 429, headers: { 'Retry-After': retryAfter }
        });
        return handleRequest(request, env);
    }
};

Cloudflare Workers 边缘计算:构建全球分布式应用 插图

Queues:可靠的背景处理

// 生产者
export default {
    async fetch(request, env) {
        const order = await request.json();
        await env.ORDER_QUEUE.send({ orderId: order.id, timestamp: Date.now() });
        return Response.json({ queued: true });
    }
};

// 消费者
export default {
    async queue(batch, env) {
        for (const message of batch.messages) {
            try {
                await processOrder(message.body, env);
                message.ack();
            } catch (error) {
                message.retry({ delaySeconds: 30 });
            }
        }
    }
};

R2:兼容 S3 的对象存储(无出站费用)

export default {
    async fetch(request, env) {
        const key = new URL(request.url).pathname.slice(1);
        if (request.method === 'PUT') {
            await env.BUCKET.put(key, request.body, {
                httpMetadata: { contentType: request.headers.get('Content-Type') }
            });
            return new Response(null, { status: 201 });
        }
        const object = await env.BUCKET.get(key);
        if (!object) return new Response('Not Found', { status: 404 });
        const headers = new Headers();
        object.writeHttpMetadata(headers);
        return new Response(object.body, { headers });
    }
};

Cloudflare Workers 边缘计算:构建全球分布式应用 插图

地理路由

export default {
    async fetch(request, env) {
        const continent = request.cf.continent;
        const backends = {
            'NA': 'https://us-east.api.example.com',
            'EU': 'https://eu-west.api.example.com',
            'AS': 'https://ap-southeast.api.example.com',
        };
        const backend = backends[continent] ?? backends['NA'];
        return fetch(backend + new URL(request.url).pathname, {
            method: request.method,
            headers: {
                ...Object.fromEntries(request.headers),
                'X-Client-Country': request.cf.country,
            },
            body: request.body
        });
    }
};

wrangler.toml 配置

name = "my-edge-app"
main = "src/index.js"
compatibility_date = "2026-01-01"

[[kv_namespaces]]
binding = "CACHE"
id = "abc123def456"

[[r2_buckets]]
binding = "BUCKET"
bucket_name = "my-app-assets"

[[queues.producers]]
queue = "order-queue"
binding = "ORDER_QUEUE"

[durable_objects]
bindings = [{ name = "RATE_LIMITER", class_name = "RateLimiter" }]

成本模型 vs 传统无服务器

Cloudflare Workers AWS Lambda
冷启动 0ms(隔离) 100-500ms(容器)
免费层 10万请求/天 100万请求/月
区域 300+ PoP 约30个区域
最大持续时间 30秒(付费) 15分钟

Workers 适用于:API 网关、A/B 测试、边缘认证验证、HTML 流式传输和缓存层。