Rust 依赖让我感到害怕

我不敢自称比那些经常在这里写博客的顶级工程师更有经验或理解,但我确实很恼火。我热爱 Rust。它是迄今为止我最喜欢的语言,我喜欢这个社区和语言的人体工程学。我已经在我的日常工作中将它融入到合适的项目中。 Rust 的依赖管理开始让我担忧。对于那些不使用 Rust 编码的人来说,Rust 通过 crates.io 提供了一个 crate 生态系统,允许用户通过 cargo add 命令轻松安装它们,或者只是将请求的 crate 和版本添加到 Cargo.toml 文件中。这种模式类似于 NodeJS 的 NPM。

优点

Cargo 非常有用,并且极大地提高了生产力,确保我不必像使用 CMake 那样四处寻找和链接文件。这还允许我经常在架构和操作系统之间切换,主要是我的 M1 Macbook Air 和我的 x86 Debian 桌面。总的来说,我不需要过多考虑包管理,而是直接开始编写代码。

缺点

不仔细考虑包管理让我变得马虎。在最近的一个生产项目中,我引入了 dotenv,这是一个我看到许多其他 Rust 开发者使用的 crate。这在多个星期内运行良好,直到最近我查看了一个 Rust 安全公告,其中提到 dotenv 已经 unmaintained。下面是一个建议的替代方案 dotenvy。整个事件让我开始思考……我真的需要这个 crate 吗?35 行代码之后,我就拥有了我需要的 dotenv 的所有部分。软件包在每种语言中都会变得 unmaintained,而引入一个可以说是微不足道的依赖项是我的选择。那么,当我拥有我 真正 需要的依赖项时会发生什么呢?

太多的代码

Tokio 是 Rust 中维护最好的软件包之一。它是与 Axum 一起添加的,Axum 是一个由同一批人开发的 webserver,它位于 Tokio (异步运行时) 之上。 Tokio 绝对是我使用过的最酷的东西之一,它自诩为一个工作窃取的多线程运行时。Tokio 的性能比我所希望的要好得多。

因此,我选择添加几个我认为需要的依赖项,使我的总 cargo 文件包含这些:AxumReqwestripunzipserdeserde_jsonTokiotower-httptracingtracing-subscriber

总的来说,我认为这个项目是微不足道的,一个处理请求、解压缩文件并具有日志记录的 webserver。

为了构建弹性的软件,我决定 vendor 我的软件包,这是一个 cargo 功能,可以下载我的所有依赖项,以便我可以在本地托管它们。

出于好奇,我运行了 toeki,这是一个用于计算代码行的工具,发现了一个惊人的 360 万行 Rust 代码。删除 vendored 的软件包后,这减少到 11136 行 Rust 代码。

现在我明白 webserver 很复杂,一个完整的异步运行时甚至更复杂。然而,根据 register article,整个 Linux 内核只有 2780 万行代码。

这仅仅是我的项目 的 7 分之一....

我怎么可能审计所有这些代码?

我个人编写的代码只有大约 1000 行。

解决方案是什么?

我不知道...... 许多人呼吁像 Go 那样在 Rust 标准库中添加更多内容,但这会导致自身的问题。Rust 定位为一种高性能、安全和模块化的语言,意味着与 CPP 和 C 竞争。这意味着它针对嵌入式设备等。添加到 std 库中的每一件事都意味着 Rust 团队需要管理和处理更多的事情。仅 Tokio 本身就拥有我见过的最活跃的 GitHub 和编程 discords。

我无法重写世界,异步运行时和 webserver 实在是太难了,而且花费的时间太长,我无法证明为这样的项目编写它们是合理的(虽然我最终应该这样做,只是为了更好地理解)。

在一次 Cloudflare 的面试中,我被告知 Cloudflare 像其他人一样利用 Tokio 并从 crates.io 中提取。他们多久审计一次这些代码?

Clickhouse 提到了 binary sizes 的问题,我怀疑他们甚至没有相同数量的 crates。

使用 cargo,没有简单的方法(据我所知)来查看哪些行 实际 被编译到最终的 binary 中,许多 crates 包含 Windows 的项目,我并不一定需要它们 (但没有官方方法告诉 cargo)。

所以现在我向你提出问题,我们该怎么办?

正在招聘 Rust 职位? 考虑我 :)