写过三年 Wasm,今天才发现它的服务端组件从来就没真正「拼」起来过——这件事今天被 WASI 0.3 彻底修了
写过三年 Wasm,今天才发现它的服务端组件从来就没真正「拼」起来过——这件事今天被 WASI 0.3 彻底修了
如果你在 2026 年还在写 WebAssembly 的服务端组件,大概率已经遇到过这个问题:单独跑一个组件没问题,一旦想把两个组件串起来,中间再加一层异步调用,整个链路就断了。文档会告诉你「不支持组合」,但不会告诉你根因在哪。
根因在 WASI 0.2 的 async 模型设计本身。
三明治问题:WASI 0.2 为什么修不了
WASI 0.2 里有 wasi:io 包,用 pollable、input-stream、output-stream 加 poll 函数,能表达异步 I/O。但这套设计碰到组件组合就失效了。
想象这样一个链路:A 组件调用 B 组件,B 再调用宿主的 HTTP 服务。
A → B → Host
在 0.2 里,每个组件都得自己跑一个事件循环。B 没办法把从 Host 拿到的 pollable 唤醒信号原样传给 A——它只能自己不停轮询来中继就绪信号。那条唤醒链就这么断掉了。这就是所谓的「三明治问题」:中间那层组件的轮询把整个 async 链切成两半。
结果就是,只要你用了流式处理或者 async API,这个组件就和其他组件「拼」不起来了。而组件模型的卖点恰恰就是「不分语言、可以拼装的二进制」——但你最重要的功能,在最常见的场景里失效了。
WASI 0.3 怎么修的
2026 年 6 月 11 日,WASI 子工作组投票批准了 WASI 0.3.0。核心变化就一句话:把 async 下沉到组件模型的规范 ABI 里。
现在事件循环只由宿主管理一份,所有组件共享它。调度和唤醒传播的所有权归运行时所有,不管 A 和 B 之间夹了多少层组件,async 都能正常工作。
实现方式是三个新原语:
async func:函数本身声明为异步,不再需要 start-foo / finish-foo / poll 三步跳。
handle: async func(request: request) -> result<response, error-code>;
stream<T>:带类型的异步数据通道,可以跨组件边界传递,0.2 里的 input-stream 是绑定在实例上的资源传不出去,现在正好反过来。
future<T>:单个值的异步完成,类似 Rust 的 Future。
还有一个设计细节:流和 future 的行为像资源类型,所有权跨组件边界传递时从调用者转移给被调用者,但不能被借用。这和普通资源类型的限制一致,但保证了所有权清晰,不会出现两个组件同时持有同一个流的情况。
性能数字是真的,但方向和你想的不一样
Bytecode Alliance 的发布文章说 WASI 0.3 可以把微服务间调用从毫秒级降到纳秒级——六个数量级。
这个数字是真的,但场景是特定的:它说的是「组件 A 调用组件 B,B 再调宿主的 wasi:http」这条链路。0.2 下这条路每次都要走网络协议栈,0.3 下因为事件循环归宿主管,宿主的 HTTP handler 可以直接调用,不用走网络协议。
但这不意味着你现在就能体验到 1000000x 提速。wasmCloud 2.5.0 发布博客里说了一句实话:「同步调用路径目前背负着大约 3.5 倍的开销,修复还只是个计划。」——0.3 修的是异步路径,同步路径现在是倒退的。
另外,guest 端的工具链在各个语言里都还在推进,线程和拼接要等下一趟车。wasmCloud 2.5.0 已经默认启用 WASI 0.3(Wasmtime 46),jco 也在跟进,但完整生态还需要时间。
现在的状态:该不该迁移
如果你正在组合组件,而这条链路里有 async——现在就该看。
如果你不是——0.2 还会继续运行,polyfill 也在,三个月后还有 0.3.2。
迁移步骤大体是机械式的:按映射表替换 wasi:io 类型,选对合适的 world(CLI 用 wasi:cli/command,HTTP 服务器用 wasi:http/service,中间件用 wasi:http/middleware),把 start-foo / finish-foo 的调用点改成 async func。
有一个实务陷阱:Wasmtime 和绑定生成器(Rust 用 wit-bindgen,JavaScript 用 jco)必须瞄准同一个 WIT 版本 0.3.0。一旦对不上,就会在实例化那一刻冒出一个很难看懂的 wrong type 错误,这类错误往往要花上大半天才能查到根源。
真正的意义:可组合性
这次发布的价值不在速度,而在于可组合性。
WASI 0.2 的 async 设计,从第一天起就知道有这个问题——但在没有把 async 下沉到 ABI 之前,没有办法修。这是组件模型最核心的能力缺口,而现在被填上了。
下一个节点是 WASI 1.0,目前没有公布日期。但 0.3 修好了 0.2 最大的架构缺陷这件事本身,已经是 WASI 历史上值得记一笔的时刻。
评论区
登录后可评论。