< 返回版块

Mike Tang 发表于 2026-11-13 13:33

spared - 用单个二进制在 Wasm 沙箱里托管多个带 SQLite 的 Rust Web 应用

spared 是一个开源的 Rust Web 应用宿主。每个应用和它自己的数据库跑在独立的 Wasm 沙箱中。作者把它比作可自托管的 Cloudflare Workers 加 Durable Objects,并强调数据隔离更好:SQLite 随应用跑在沙箱里,而不是放在宿主中。一台服务器上的一个二进制就可以托管许多相互隔离的应用。应用本身是 Rust crate,需要用 rustup 安装 Rust,并编译到 wasm32-wasip2。

热请求的中位延迟比 workerd 快 2.6 倍(148 微秒对 388 微秒)。在 14 项后端任务里,spared 上的 Rust 有 8 项快于 workerd 上的 JavaScript;crypto、gzip 和 JSON 仍是 JavaScript 更快,因为 workerd 在这些路径上调用原生代码。空闲应用处理下一次请求约 0.9 毫秒(workerd 为 1.07 毫秒)。机器重启后,每个应用的第一次请求会更慢,直到代码回到页缓存。

同类宿主里,celld 把 SQLite 放在宿主侧,形态是单节点或一组节点上的 JavaScript;Spin 也把 SQLite 放在宿主侧,使用池化实例和 Wasm 组件;workerd 的 SQLite 在宿主进程中,是可自托管的 JavaScript 运行时;wasmCloud 通过宿主插件接入、本身不带 SQLite,跑在 Kubernetes 加 NATS 上,应用是 Wasm 组件。spared 的取舍是:每个应用自带一份 SQLite,应用数大约在 20 个以内时内存低于 workerd,再多就会更高(200 个应用时 889 MiB 对 574 MiB),但内核无法回收的内存在各个规模都更低(200 个应用时 108 MiB 对 516 MiB)。沙箱里的 SQLite 大约比原生 SQLite 多 1.85 倍 CPU。每个应用一次只处理一个请求,不同应用可以并行。服务只提供明文 HTTP,没有 TLS,需要在前面加代理。

当前版本是 0.0.1-preview,已在 Linux x86_64、glibc 2.35 或更新版本上测试。spared setup 会用 rustup 加上 wasm32-wasip2 target,把 wasi-sdk 25 放到 ~/.spared,并把 SQLite 编译成 Wasm,这一步大约一分钟;之后在 4 核 Linux 虚拟机上,应用首次构建约 12 秒,后续构建为数秒。若不先做这一步,首次构建会自己编译 SQLite,大约也要一分钟。本地可以用 spared serve 启动(应用在 127.0.0.1:8080,管理接口在 127.0.0.1:8081),再用 spared new 和 spared deploy 生成并部署应用。接下来计划加强资源限制、支持时间点恢复,并在清单里加入按应用的部署令牌和磁盘配额。项目还没有外部审计,不适合托管一旦沙箱失效就会造成严重损害的代码。许可证是 Apache 2.0。

https://github.com/michaelmagan/spared

Relax - 用 Rust 编写的实时编译器与 JIT 运行时

Relax 直接从源码运行 Cargo 包,过程中不经过 rustc、LLVM 和链接器。函数在第一次被调用时编译,热点在程序运行期间继续优化,对源码的修改可以补进正在运行的进程并保留状态。它面向编辑—运行循环,发布仍使用 cargo build --release 的产物。

在 M4 MacBook 上,一个大型 3D 游戏从干净检出到第一帧,Relax 用时 11 秒;同一游戏第二次运行、无需重新编译时为 1.15 秒。rustc 加 Cargo 大约先构建 3 分钟再启动。小型应用冷启动到第一帧 3.7 秒,热启动 0.41 秒。保存文件后重跑 92 个测试约 2.2 秒。实现是一个约 43.8 万行的 Rust library,没有 crates.io 依赖。

relax run 会打印 relax-remote: pid <pid>;除 run 和 test 外的命令通过 relax inspect <pid> 发给正在运行的程序。

  • 保存即构建:只重新检查并重新编译改过的函数,再换入运行中的进程。调用到还不能编译的代码会等待修复。入口是 relax run <package>。
  • relax test --live <package> 让测试保持热状态,并重跑进入了所改函数的测试。
  • panic 的线程会停驻且栈保持完整(终端前 10 分钟,无人值守 2 秒)。可用 panics、locals、panic=P1、eval <expr>、resume 查看局部变量、在该栈帧求值,再 unwind 或重跑可重启函数。
  • break <file>:<line> 提供不依赖调试器的断点,命中后线程停在调用处。
  • why-hung 判断死锁、阻塞、忙碌或空闲,并给出等待链和线程栈。
  • prof 与 why-slow 采样 JIT 和原生帧,给出每线程 CPU、热点函数及其最热行、带层级的调用树和火焰图栈。
  • 飞行记录器常开且内存有界,保留最近一段时间的线程、等待、编译和事件;panic、故障或超过 1 秒的卡顿会自动保存,也可 rec save。
  • memory 与 heap 按种类查看 RSS、使用中和持有的空闲 malloc、Relax 自身占用,以及按分配栈划分的堆和快照间的泄漏候选。堆跟踪目前仅支持 Linux x86-64 和 macOS arm64。

相对针对本机 CPU 的 --release,优化后的代码大约慢 1.14–1.26 倍,密集数值循环约 2.3 倍,尚未做向量化。编译器、缓存和已发布代码与程序共享进程,JIT 代码只追加。大型包上冷的 relax check 比 cargo check 更慢、更占内存,一次编辑也可能重新检查超出必要的部分。运行时每个函数在执行前做类型检查,借用检查默认在后台进行,除非传入 --check-first。函数体可以热补丁;结构体布局、import、trait 或 impl 头部以及宏的改动,需要 session relaunch 后重启会话。并非每个 crate 都能运行,已知缺口列在 KNOWN_GAPS.md。

https://makepad.github.io/relax

Composable Real-Time Platform Design in Rust - 研究如何用内存安全的 Rust 编写有严格时限的嵌入式软件

必须在严格时限内响应事件的嵌入式软件,目前仍多以 C 编写。C 对编程错误提供的防护很少,而更安全的语言通常又依赖一些使时序难以预测的做法。坦佩雷大学的 Henri Lunnikivi 在计算机工程领域的博士论文中,研究如何用内存安全的 Rust 为基于开放 RISC-V 架构的处理器编写这类程序。论文题为 Composable Real-Time Platform Design in Rust。

论文以其所在研究组开发的可预测微控制器 Atalanta 为例,用时序模型把任务开始前的最大延迟计算到时钟周期。结果表明,内存安全编程与精确时序并非互斥,或有助于汽车、工厂机械等时序关键设备的开发者写出既更安全、又可预测的软件。

该论文将于 2026 年 11 月 30 日在坦佩雷大学信息科技与通信科学学院公开答辩。Opponent 为德国慕尼黑工业大学的 Wolfgang Ecker 教授,Custos 为该学院的 Timo Hämäläinen 教授。

https://www.tuni.fi/en/tau/news-and-events/henri-lunnikivi-real-time-embedded-computers-can-be-programmed-memory-safe

Zellij - 0.46 将终端复用器扩展为可独立运行并嵌入应用的终端

Zellij 0.46 已发布。它继续管理会话、窗格、标签页和 Rust wasm 插件,同时内置终端,可以完全替换现有终端,并与桌面和系统托盘集成。这一版还包括 attention inbox 和 session previews。

新的 Distributions 功能允许 Rust 开发者把 Zellij 作为库引入自己的项目,用来做跨平台应用。应用可以渲染用 Rust 编写的自定义终端界面,既能在另一个终端中运行,也能独立运行,跨平台分发由该功能处理。不需要的 Zellij 品牌和界面可以去掉,从而把产物完全白标。

https://zellij.dev/news/terminal-inbox-session-previews

https://www.reddit.com/r/rust/comments/1xtercc/zellij_0460_just_released_rust_developers_can_now/

--

From 日报小组 Mike

社区学习交流平台订阅:

友情赞助:

评论区

写评论

还没有评论

1 共 0 条评论, 1 页