浏览器里跑 POSIX 多进程内核?
fork()。听起来像个科幻概念验证,但他们真在浏览器里跑起来了 Nginx、PHP、Python、Redis、MariaDB,甚至把 WordPress Playground 整个服务端塞进去了。我第一反应是:这性能能看?毕竟 WASM 还没 SIMD 宽表、没真正的 64 位原子操作、系统调用还得跨 Worker 通信。但看完架构说明和 Demo 后,我不得不承认——在“不妥协 POSIX 兼容”这个前提下,它跑得比我想象的要顺滑得多。
架构里有几个细节值得玩味
- 单 Worker 内核 + 进程隔离:内核集中在一个 Worker 里维护全局状态(VFS、PID 表、信号量),用户进程各自一个 Worker,内存互不干扰。这比早期「全在一个 Worker 里跑用户态」的方案干净得多,也避免了单线程瓶颈。
- 系统调用走 SharedArrayBuffer + Atomics.wait/notify:零拷贝传参、阻塞语义原生映射,延迟在亚毫秒级。代价是必须开启
cross-origin-isolation,部署时得配好COOP/COEP头,否则直接跑不起来。 - VFS 镜像懒加载:Demo 里的
vim甚至不是预装的,第一次敲命令才按需拉取对应的.vfs.zst块。50 MB 的镜像首屏加载慢是慢,但冷启动后体感接近本地。 fork()真实现了:子进程 Worker 启动时把父进程内存快照postMessage过去,配合Atomics同步页表。听起来重,实测bash里跑make -j4也能跑通。
实际把玩了两个 Demo
Shell 镜像(bash + vim + nethack):
进去就是个熟悉的终端,ls、cat、grep 全是原生编译的 GNU coreutils。vim 能正常高亮、补全、甚至跑 :!make。nethack 那会儿我还怀疑是不是套了个终端模拟器——确认过,是真跑在 Kandelo 进程里的 ELF 二进制。
LXDE 桌面 PoC:
这是最离谱的。Xvfb + Openbox + pcmanfm + lxterminal 全部跑在浏览器标签页里,鼠标键盘事件经由 SendInput 系统调用注入内核再分发给 X 服务器。拖窗口、打终端、跑 htop 看进程树,除了偶尔掉帧,交互逻辑居然是通的。当然,别指望拿它做日常驱动——红黑树调度器在 WASM 里跑 fork bomb 还是会把主线程卡死。
真正的疑问点
1. 文件系统持久化:现在靠 OPFS(Origin Private File System)落盘,关标签页数据还在,但跨域、跨浏览器、跨设备同步完全靠自己造。要做成真正的「浏览器原生 IDE」或「协作沙箱」,这层得重写。
2. 网络栈:目前只能走 WebSocket 代理或 WebRTC data channel,真 TCP/UDP 没戏。跑 Nginx 只能反代到 localhost,跑 Redis 更是只能单机玩。要把分布式系统塞进去,得自己在用户态实现一层虚拟网卡。
3. 移动端:作者自己承认「YMMV on mobile」。iOS Safari 对 SharedArrayBuffer 的支持依然阉割,内存上限也低,50 MB 镜像加载随时会被 OOM Kill。
4. 供应链信任:SDK 里把现有 Linux 二进制通过 wasix/wasi-sdk 重编译,工具链版本一锁死,升级 glibc、musl、openssl 全靠上游发布 WASI 目标三方包。想用最新 CVE 补丁?等着吧。
我会怎么用它?
不指望它替代服务器端容器,但作为「零安装、零配置、可嵌入网页的临时 Linux 环境」,场景很明确:
- 文档站点内嵌可运行的代码片段(不止 JS,C/Rust/Go 全能跑)
- CI/CD 的快速预检环境:PR 提交前在浏览器跑一遍
make test,挂了再推远程 - 教学演示:学生打开网页就有完整
gcc/gdb/valgrind工具链,不用装 WSL、不用配 Docker - Agent 沙箱:让 LLM 生成的代码在隔离进程里跑,崩了也就炸一个 Worker
别被「POSIX 兼容」忽悠了
Kandelo 现在的兼容性是「能跑过测试套件的子集」,不是 full POSIX.1-2017。epoll、io_uring、cgroup、namespace 这些内核级特性全靠用户态模拟或直接存根。想跑 systemd、跑 Kubernetes、跑需要真实硬件虚拟化的 workload?洗洗睡。
但话说回来,**能在浏览器里不带插件、不装运行时、直接 git clone 一个 Linux 仓库