一个人三个星期,把 Cloudflare Workers 全家桶装进一个二进制
- elliothux 三周内打造 Cloudflare Workers 兼容平台 open-compute
- open-compute 绕过 workerd 运行时,直接使用 Cloudflare 同款 C++ 运行时
- open-compute 利用 workerd 的 Durable Objects 实现多租户 DO
- open-compute 使用 SQLite 存储平台元数据和调度信息
- open-compute 提供 wrangler 接入和管理界面,实现 Cloudflare API 部分功能
2026 年 8 月 23 日,GitHub 上多了一个新仓库。
三周后的今天,它有 735 颗星、21 个 fork,版本号走到 v0.1.7,今天早上刚发的。贡献者列表从头到尾只有一个人,elliothux,311 次提交。仓库叫 open-compute,自我介绍一句话,单个二进制跑起来的 Cloudflare Workers 兼容平台,KV、D1、R2、Durable Objects、Queues、Workflows 全都在里面。
说真的,第一眼我以为又是那种半成品的 Workers 兼容层。把源码拉下来读完才发现,它把最难的那一步直接绕开了,而整个项目的成败都押在这个取舍上。
它补的是 workerd 没做的那一半
上一篇刚拆过 workerd,Cloudflare 开源的 Workers 运行时。那篇有个没展开的事实,workerd 只开源了运行时,没开源平台。open-compute 作者在 README 里的表述更直接,翻译过来是,workerd 是运行时,不是平台,它执行隔离的 Worker 很出色,然后就没有然后了。多租户路由、持久状态、调度、部署生命周期、控制 API,全都没有。想在自家机器上跑 Workers 生态的人,这些都得自己造。
open-compute 造的就是这一层。落地形态克制到近乎偏执,一条安装脚本拉下来一个叫 ocd 的二进制,指给它一个数据目录,就开始服务流量了。没有 Docker,没有 Kubernetes,没有 Redis,没有独立的 Postgres。
先看它声称做到了什么。兼容清单上 Workers、KV、R2、D1、Durable Objects、Alarms、Queues、Cron、Workflows、静态资产、服务绑定、Cache、Vectorize、WebSocket Hibernation 全是 100% 的绿条,管理面覆盖 Cloudflare v4 API 的九成,官方 SDK 和 wrangler 可以直接指过来用。README 的口号起得很硬,Proof not promises,同样的测试夹具在 open-compute 和真实 Cloudflare 上对拍,七个核心产品面 7 比 7,追踪着 2203 个稳定 API 成员和重载,强制九成以上行覆盖率。
冷静看,进度条全绿和「生产可用」之间还隔着不少东西,后面细说。先看它最值得学的那个决定。
最聪明的决定,是不自己写运行时
复刻 Workers 生态,所有人都会先撞上同一堵墙,JavaScript 运行时的行为兼容。fetch 的细节、streams 的背压、Date 的解析,每一条都是能耗掉几个月的坑。常见路线是自己做 V8 绑定或者嵌一个轻量 JS 引擎,然后掉进 API 行为差异的无底洞。
open-compute 的答案是不写。它把 workerd 的二进制直接 vendor 进仓库,租户代码跑的就是 Cloudflare 同款的那个 C++ 运行时。
而且 vendor 的不是上游原版,是作者自己维护的 fork。fork 在上游基础上加了平台需要的能力,比如配置里新增的 workerLoader 绑定,让一个宿主 Worker 可以按需加载别的 Worker 模块,还有给进程控制用的 --control-fd 参数。这两个扩展后面都会用到。
供应链的做法偏执到可以单独学。二进制以压缩包形式跟着仓库走,构建脚本硬校验来源,仓库地址必须是 elliothux 名下的那个 workerd fork,构建目标必须是 workerd 官方的 bazel target,SHA-256 钉在 lock 文件里。Rust 侧的 build.rs 构建时再验一遍哈希,运行时解包出来还要再验一遍,落到内容寻址的目录里原子发布。全程不联网下载,不查 PATH。
跑起来的形态更简单粗暴。整个平台只有一个 workerd 进程,crates/runtime/src/supervisor/spawn.rs 里拼出的启动参数是这样的,serve 模式,配置从标准输入喂进去,控制通道走文件描述符 3,HTTP 端口随机绑在本机回环,子进程的环境变量整个清空。
那租户的 Worker 怎么办。
这就是 workerLoader 的用场。workerd 里跑着一个 loader-host 系统 Worker,平台侧部署新版本不用重启运行时,loader-host 按需从一个私有的 runtime-source 回环端点拉取租户模块,现场装配。你猜怎么着,所谓毫秒级冷启动,就是 isolate 复用加模块惰性加载这么来的,没有魔法。
一个 Durable Object,套着所有人的 Durable Objects
全家桶里最难复刻的是 Durable Objects,它是 Workers 生态里最像数据库又最像 actor 框架的东西,单例语义、事务存储、alarm 调度,坑坑要命。
open-compute 的实现是个套娃。workerd 里跑着一个 do-router 系统 Worker,导出一个叫 DoHost 的 Durable Object 类,配置里的 uniqueKey 是 open-compute-do-host-v1。所有租户的每一个 DO,都通过 router.ts 里那行 env.DO_HOST.get(env.DO_HOST.idFromName(authority.hostKey)) 哈希进这同一个命名空间。DoHost 实例自己用 storage.sql 建表存元数据,再按租户声明动态加载真正的 DO 类。
说人话,它用 workerd 原生的 DO 当容器,把所有租户的 DO 装进去。单例由谁保证、input gate 由谁保证、磁盘存储由谁管,全是 workerd 已经写好的逻辑,平台一行都不用重写。而删除授权、路由、alarm 的权威状态放在 ocd 自己的 SQLite 里,通过两个带令牌的内部端点和运行时同步,防陈旧的围栏协议把 alarm 派发的结局枚举成 Success、Stale、NotDue、Retry、Exhausted 五种,每种都有明确的处理路径。
剩下的部分,SQLite 和回环地址
存储没有引入任何外部组件。平台元数据、调度、日志各占一个 SQLite 文件,data_dir.rs 里对应 control_db_path、scheduler_db_path、observability_db_path 三个函数。KV 每个 namespace 一个 SQLite 文件,D1 每个数据库一个文件还带时间旅行,Queues 和 Workflows 的状态机铺在这几个库上。
R2 的对象字节走单独的 ObjectBackend,本地模式下是 XChaCha20-Poly1305 加密的分块容器,文件头八个字节的魔数是 OCOBJ001,也可以切换成对接 S3。secret 全部加密存储,主密钥落在数据目录的 keys 下。
wrangler 的接入方式很讨巧。ocd wrangler 子命令会把当前进程替换成项目里钉死的 wrangler 4.127.1,注入本地的 API 地址和令牌,顺手把 CLOUDFLARE_API_KEY 这类真实云凭证的环境变量全清掉,防止误操作打到真 Cloudflare 上去。管理面实现了 /client/v4 路由树的九成,官方 SDK 换个 base URL 就能用。
最妙的细节是它自带的 dashboard。内嵌的仪表盘静态资源不是起个文件服务器完事,而是被发布成一个 AssetsOnly 版本的系统 Worker,从 workerd 里跑出来。自己的控制台跑在自己的运行时上,狗粮吃到这个份上。
代价清清楚楚写在错误码里
取舍的另一面,仓库自己一点没藏着。
最要命的是单点。整个平台一个 workerd 进程,爆炸半径就是它。issue #67 报告动态加载的子 Worker 里一个死循环,整个运行时直接卡死,没有任何自动恢复,所有租户一起拿到 RUNTIME_UNAVAILABLE,直到人工重启进程。#62 报告一次部署把共享运行时干崩。#61 报告 cron 的未知结局无限重试,能阻塞住所有部署。这些不是孤例,源码里写得明明白白,runtime_bridge/transport.rs 的 endpoint() 函数开头就检查 supervisor 状态,只要运行时不在 Running 态,一律返回 RUNTIME_UNAVAILABLE。
其实吧,这些毛病的根子是同一个,单共享运行时的取舍。它换来了毫秒冷启动和零进程编排,代价是把租户间的隔离边界从进程级降到了模块级。单人小团队自用,这个交换划算,对外做多租户服务,慎用。
可持续性也要掂量。贡献者一个人,版本号 0.1.7,AGENTS.md 里的 Day1 规则写得直白,1.0 之前不保证持久化数据跨版本兼容,破坏性变更一律 fail closed。态度很诚实,但生产数据请自求多福,备份策略自己写好。wrangler 的版本耦合也翻过车,issue #66,wrangler 上游发了个新的元数据字段,平台侧校验不认识,直接 400 拒绝,两边版本得咬合着升。
一个人三周怎么干出来的,仓库自己会说话
这个速度本身就值得拆,线索全在仓库里。
AGENTS.md 是写给 AI 协作者的操作系统契约,什么情况直接动手、什么情况必须先问,粒度比多数公司的工程规范还细。里面定义了 Day1 架构规则和复杂度预算,目标场景钉死在单机小团队自部署,明说不为长尾行为引入分布式系统的机器。
CR.md 是分阶段的代码审查记录,每条问题带着编号和修复证据。docs/implemented 目录下躺着 50 多份逐阶段的验收文档。最有趣的是 .agents/skills 里有个 anti-cheating 技能,专门审计 AI 协作者有没有为了过测试在生产代码里写死测试用例,防的就是模型作弊这条路。
AGENTS.md 里还有一句提醒,别动父项目 Lynx OS。这个仓库是一个更大计划里拆出来的子系统。
把这些拼起来,2026 年一个人的交付方式已经变了。十个 crate 加一个 workerd fork 加一个 dashboard,三周,流水线是 AI 写、规则约束、审查收口。这条流水线本身,可能比 open-compute 这个产品更值得抄作业。
别重造内核,去做发行版
坦白讲,open-compute 最值得带走的不是任何一行代码,是一个分工判断,内核和发行版分开做。
workerd 是内核,Cloudflare 养着,每天发版,兼容性修复免费坐享。open-compute 是发行版,管打包、存储、控制面、运维体验。Linux 世界用三十多年验证过这个分工,现在有人把它搬进了 Workers 生态。借内核的前提是内核有清晰的边界和稳定的接口,workerd 恰好有,capnp 配置、控制文件描述符、目录服务,fork 加两个绑定就能当平台的底盘用。
选型结论分两种情况。单人或者小团队,想把 Workers 项目搬回自己的机器又不想改代码,现在就可以拿它玩,数据备份自己负责。对外多租户服务,等 1.0,等 bus factor 缓解,尤其单进程单点那笔账要重新算。而对于想理解 Cloudflare 平台层长什么样的人,这是当下唯一的开源标本,毕竟官方那套不开源。
上一篇说,workerd 把版本号做成了日期。这一篇,open-compute 把平台做成了一个文件。一个是地基,一个是照着地基盖的样板间,连着读,Workers 生态的上下两层就都齐了。

评论互动