Safety in an Unsafe World:Netstack3 用类型系统把“buggy programs don’t compile”推到协议正确性
这篇文章来自 RustConf 2024 演讲的整理版,但内容一点都不轻。作者拿 Fuchsia 的 纯 Rust 网络栈 Netstack3 当主线,先摆出一个很硬的结果:在近一年的大规模 dogfooding 里,这套实现了大量协议、跨 63 个 crate、约 19.2 万行代码的网络栈,现场环境里只抓出了 3 个 bug;而上线后,相比旧版 Netstack2,崩溃率还直接降了一个量级,内存占用也明显下降。
作者要讲的核心并不是“Rust 天生万能”,而是更进一步:Rust 默认只帮你兜住内存安全和线程安全,但真正复杂系统里的大量 bug——协议状态机、跨模块约束、业务不变量——并不会自动因为你用了 Rust 就消失。Netstack3 的做法,是继续把 不变量、状态转换、抽象边界 编进类型和 API 设计里,让外部安全代码根本没机会构造出错误状态,也就是把“buggy programs don’t compile”从语言层扩展到系统设计层。
这种思路对基础设施 Rust 项目尤其有启发。它说明 Rust 的上限不只是“写得更不容易崩”,而是可以把一部分过去只能靠 code review、测试、线上经验慢慢补的正确性约束,前移到编译期去表达。对做协议栈、数据库、编译器、中间件的人来说,这篇文章非常值得反复看。
原文链接:https://joshlf.com/posts/safety-unsafe-world/
Kata Containers 4.0:默认运行时正式切到 Rust,容器沙箱栈完成平台级换芯
这次 Kata Containers 4.0 最值得看的,不是零碎功能更新,而是它把那条筹备多年的 Rust 运行时重写 正式扶正成默认路径,老的 Go 运行时则进入弃用通道,只会保留到 5.0,后续也不再接收新特性。换句话说,Kata 这次不是“补一版功能”,而是把整个平台底座直接换芯。
从发布说明看,这套默认 Rust 运行时已经覆盖 x86_64、aarch64、s390x,同时继续围绕“容器速度 + 虚拟机隔离”这条路线强化能力:支持 QEMU、Cloud Hypervisor,还把 Rust 写的 Dragonball hypervisor 纳入正式支持范围;在设备与资源侧则继续补齐 block device、hotplug、virtio-mem、多队列网络、VFIO coldplug、Kubernetes 资源核算等关键能力。
更重要的是,Kata 4.0 的叙事已经明显从“更安全的容器”扩展到了 AI / 多租户工作负载的沙箱基础设施。当容器沙箱、hypervisor、runtime、编排接口这一整层都在往 Rust 上集中,Rust 在云原生安全底座里的存在感又往前拱了一大步。
原文链接:https://opensourcewatch.beehiiv.com/p/kata-containers-4-0-is-less-a-new-feature-release-than-a-platform-reset-to-rust
Tokio / Smol / Glommio 90 组对比:HTTP 负载下 work-stealing 和 executor-per-thread 到底谁更能打
这篇基准文章很有料。作者围绕 Rust 生态里几条常见异步运行时路线,搭了一个带真实业务影子的 HTTP/2 测试框架:create_order、index_page、read_order 三类请求,分别模拟 IO 密集、CPU 密集和混合负载,再把 线程数、流量分布、连接规模、工作负载结构 组合成 90 组场景,去对比 tokio 的 work-stealing 与多线程共享端口的 executor-per-thread 模式,以及 smol、glommio 这类更偏每线程本地执行器的方案。
文章里最有意思的结论不是“谁永远最快”,而是 性能高度依赖负载形态。在流量分配更均匀、CPU 更重的场景里,executor-per-thread 往往能靠本地缓存命中和少同步开销拿到更稳的尾延迟;但在更偏 IO、任务分布更不均衡的情况下,work-stealing 的全局调度又可能更占便宜。作者把“到底该选 Tokio 默认多线程,还是每线程单独跑本地执行器”这个经常被经验主义处理的问题,第一次做成了比较系统的实验。
对 Rust 服务端工程来说,这类文章的价值很直接:它提醒你 运行时模型本身就是架构选择的一部分。不是所有 Web 服务都应该默认接受同一套 executor 设计,尤其在高并发、HTTP/2、多核部署、Noisy Neighbor 明显的环境里,调度策略本身就会决定你拿到的是吞吐、尾延迟,还是两边都不上不下。
原文链接:https://c410-f3r.github.io/thoughts/work-stealing-vs-executor-per-thread-evaluating-different-http-server-workloads-with-tokio-smol-and-glommio/
从零手写 Rust arena:把 UnsafeCell、raw buffer 和类型化句柄一层层拆开
这篇文章不是泛泛讲“arena allocator 有什么用”,而是真的从最朴素的 Vec<T> 版本开始,逐步把 Rust 里 arena 为什么难、难在哪、最后为什么往往要碰 unsafe 讲清楚了。作者先用数据库、脚本运行时这类高频临时对象场景解释 arena 的现实价值:预分配大块内存、顺序推进指针、整批复用空间,换来更少碎片、更低分配开销、更好的 cache locality。
真正值得看的,是它没有停在“固定容量 Vec”这一层,而是继续往下拆:为什么 Vec<String> 只把 header 放进 arena、底层数据仍然散落在堆上;为什么 borrow checker 不允许你轻松拿到多个指向不同槽位的 &mut;为什么想同时支持 不同类型、多个可变引用、正确 drop 动态对象,最后就得自己维护 raw buffer、对齐、cursor、slot 元数据,以及 UnsafeCell 驱动的内部可变性。
这类文章对 Rust 读者很友好的一点,是它没有把 unsafe 写成黑魔法,而是把“什么时候必须自己接管编译器原本替你保证的那部分东西”讲得很具体。对想理解内存池、对象 arena、ECS、数据库执行器甚至自定义分配器的人来说,这是一篇很适合顺着源码边读边想的材料。
原文链接:https://rushter.com/blog/rust-memory-arenas/
评论区
写评论还没有评论