使用Cloudflare Durable Objects构建一个分布式限流器
Cloudflare Durable Objects(DO)是一种有状态的计算资源,与Cloudflare Workers不同。DO提供了独立的存储空间和唯一的ID访问,适合处理特定场景,如分布式限流器。DO的特性包括数据隔离和强一致性,非常适合WebSocket服务、多人协作和定时任务。通过构建分布式Token Bucket限流器的例子,可以看到DO的强大之处,包括简单的状态管理、低延迟和直观的开发体验。DO的潜力远不止于此,可以用来实现更复杂的应用,如实时游戏逻辑和轻量级数据库应用。
Cloudflare Durable Objects(简称 DO)是一个这非常有意思的产品。初看文档时,很多人可能和我一样,对其概念感到一头雾水。但真正上手使用后,你会有一种豁然开朗的感觉。
简单来说,DO 也是一种计算资源,但它与 Cloudflare Workers 有着本质的区别:Workers 是无状态的 (Stateless),而 Durable Objects 是有状态的 (Stateful)。
为什么我们需要 Durable Objects?
通常我们使用 Workers 时,脚本跑完就销毁了,内存中不保存任何状态。虽然我们可以引入 KV、D1 数据库等外部存储来实现持久化,但 DO 提供了另一维度的解决方案。
DO 的每一个实例都有自己独立的存储空间(支持 KV 键值对或 SQLite),而且通过唯一的 ID 访问。这意味着:
数据隔离:每个 DO 实例的数据是独立的,不共享。
强一致性:同一个 DO 实例的请求是排队处理的,这为处理并发和状态同步提供了天然的优势。
这就让 DO 非常适合处理一些特定场景,比如我们今天要实现的——分布式限流器。
典型的应用场景
除了限流器,DO 的特性还非常适合以下场景:
WebSocket 服务:维持长连接状态。
多人协作:例如 Google Docs 这里的实时编辑,每个人都能实时看到别人的动作。
定时任务:利用 DO 的
setAlarm实现精准的定时触发。
这就好比你拥有了一个不仅能计算,还能"记住"事情的小型服务器,但它又是完全 Serverless 的,无需关心扩展性和运维。
实战:构建分布式 Token Bucket 限流器
分布式限流的核心在于:每个用户(或 IP)都有一个独立的计数器。这个数据虽非核心业务数据,但对实时性和一致性要求很高。DO 的独立存储特性完美契合这一需求。
我们将使用经典的 令牌桶算法 (Token Bucket) 来实现。
核心代码实现
下面是一个完整的 RateLimiter 类实现。这段代码利用了 Cloudflare Workers 的 RPC 特性,让调用 DO 就像调用本地方法一样简单。
如何调用这个限流器?
使用起来非常简单。我们通常会根据 userId 或 IP 来生成唯一的 DO ID,这样每个用户就拥有了独立的限流器实例。
总结
通过这个简单的例子,我们可以看到 Cloudflare Durable Objects 的强大之处:
极其简单的状态管理:不需要额外部署 Redis,状态就存在代码旁边。
低延迟:DO 实例通常会在靠近用户的边缘节点运行(尽管 DO 目前有地域限制,但配合 Workers 依然很快)。
开发体验:基于 RPC 的调用方式,让分布式系统的开发变得像写单机程序一样直观。
当然,DO 的潜力远不止于此。我们可以用它来实现更复杂的 WebSocket 消息广播、实时游戏逻辑,甚至是轻量级的数据库应用。如果你对 Serverless 架构感兴趣,Durable Objects 绝对是一个值得深入挖掘的宝藏.