Rust 越来越受欢迎。通过 2022 年 StackOverflow 开发者调查,我们可以看到很多人对 Rust 感兴趣。
Rust 已经连续 7 年成为最受喜爱的编程语言,87% 的开发者表示他们想继续使用 Rust。
Rust 也与 Python 并列成为最受期待的技术,TypeScript 紧随其后。
最受期待
图片
最受喜爱 vs 最令人憎恶
图片
但 Rust 有一定的学习曲线。
这让我想分享我的 Rust 学习之旅,为什么选择 Rust, 以及如何学习 Rust。
接触 Rust
我在 Rust 刚刚发布的时候就听说过它,我的印象是它是一种系统编程语言,可以替代 C/C++, 而且足够安全。但是我当时并没有真正学习和使用它 (我只写过 "Hello World"!)。
回到 5 年前,我正在领导公司基础设施向云原生架构的转型。
我需要构建一个完全基于 Prometheus 的监控栈,来替换公司内部使用了 10 多年历史的一些监控软件,如 Nagios、Zabbix 和 Graphite。
是的,你没有看错,我们使用了很多监控软件。这主要出于几个原因:
- 单一的软件无法满足所有需求
- 团队分散,大多数时候引入新软件只是为了满足特定需求,而不是解决问题
总之,这是一些历史原因。
从我之前提到的情况来看,我们有一套自研的监控软件,历史超过 10 年,可以看出,我们的基础设施迭代速度很慢。
因为我们有自己的物理数据中心,这也导致了很多旧机器在我们的服务器上没有更新过。(这也是我后来使用 Rust 的一个原因)
我首先在一个新启用的小数据中心 (约 400 台机器) 替换了监控栈,效果很好。使用 Prometheus 完成了该小数据中心所有服务器及其运行的各种服务的监控。我们还在 Grafana 上创建了仪表板,并通过 Alertmanager 创建了告警通知。
后来,我在两个数据中心推广了这种转型,整体来说比较顺利,包括 Kubernetes 的监控也是在这个过程中完成的。
但是当它实施在最后一个数据中心时,我遇到了最大的挑战。
node_exporter 无法在某些机器上启动,一些机器在运行一段时间后会自动崩溃。
我开始调查这个问题。对于自动崩溃的问题,我暂时通过添加一个重启脚本来修复了。
我主要关注的是为什么 node_exporter 无法启动。我发现这部分机器的操作系统是 CentOS 5, 内核是 2.6.18。
我发现社区中已经有类似的问题: https://github.com/prometheus/node_exporter/issues/691
与此同时,我也注意到 Go 文档明确指出 CentOS 5 不受支持,需要 2.6.32 或更高版本的内核。
(我忘了在我当时排查问题时,所需要的依赖的最低版本,但通过 Web archive[1],我看到 2017 年需要的最低内核版本是 2.6.23)
经过一些搜索,我也看到了类似 "如何在 CentOS 5.9 上安装 Go 1.1" 的内容,但同时也提到了一些已知的问题。
所以我不打算继续在这里浪费时间。
我想自己换个技术栈重新实现一个类似 node_exporter 的工具,也就很自然的可以解决上述自动崩溃的问题了。
经过一番权衡,最终,我使用 Rust 实现了一个类似 node_exporter 的工具,并完成了监控系统的升级和转型。
这就是我开始在生产环境中使用 Rust 的起点。
接下来,让我介绍为什么我选择 Rust。
图片
为什么选择 Rust
我上面介绍了一些背景。当时最简单的选择应该是 Python, 它足够简单,生态也很丰富。与此同时,我在 Python 开发也有多年经验,我可以快速构建所需的工具。
当时我不选择 Python 的原因是:
- 并非所有这些机器都有 Python 环境,Python 版本也不尽相同。我被要求尽量不要修改这些机器上的环境;
- 因为我可能会对我开发的新工具做一些修改,所以后续的分发可能不太方便;
然后我重新思考了我的目标:
- 可以编译成二进制可执行文件,方便分发和部署。我使用 Ansible 进行统一部署。
所以更合适的选择是 C/C++/Rust。
我在 C 开发上有更多经验,C++ 也有一些经验。对于我的第一个需求,上述三种语言都可以很轻松地实现。
当大多数人比较 Rust 和 C/C++ 时,他们在比较它们的性能和安全性。
而在当时我的用例中,我认为在其他两种语言中的结果不会比 Rust 差,尽管这也是一个考虑因素。而且当时我刚开始学习 Rust, 我的 C 实现可能会比 Rust 更好。
但我想挑战自己,尝试一些新事物,而且就 Prometheus 监控而言,C/C++ 相关的生态并不太活跃。另一点是我认为 Rust 将有很大的发展前景。
所以最终我选择了 Rust。
我是如何学习 Rust 的
Rust 并不简单,它与其他语言也有一些不同,所以在其他语言中有效的一些做法在 Rust 中可能无法奏效。
由于我有一个具体的问题需要解决,我需要实现一个 node_exporter 来完成监控栈的转型。所以我是通过 "边学边做" 的方式来学习 Rust 的。
我首先快速浏览了以下内容:
- The Rust Programming Language[2]: 这本书非常完整,我一开始并没有完全读完。取而代之的是,使用它来理解 Rust 的主要概念和一些用法。
- Rust By Example[3]: 这里有很多示例,你也可以通过练习这些示例来增加对 Rust 的熟悉度;
- Rust std lib docs[4]: 标准库文档,快速概览,了解一些关键词、模块等。但最初没必要完整阅读。
通过这种方式,我很快就实现了一个基本的 node_exporter 版本。然后继续迭代并应用到生产环境,完成了 Prometheus 监控栈的构建。
后来,我继续在 Rust 中实现了一些小工具,学习了它的最佳实践,并学习了一些用 Rust 实现的开源项目,以增加我的 Rust 经验。
推荐一些 Rust 学习资源
现在有很多 Rust 的学习资源。除了我前面列出的,我还推荐以下免费内容:
- Take your first steps with Rust - Training | Microsoft Learn[5]
- rust-lang/rustlings: 一些小练习,让你适应阅读和编写 Rust 代码!
视频:
- Rust Crash Course | Rustlang - YouTube[6]
- Rust Tutorial - YouTube[7]
- Rust for Beginners - YouTube[8]
总结
这就是我的 Rust 学习之旅的开始,它一直在继续。
尽管我仍然持续的关注云原生和 Kubernetes 相关的技术,并且我写 Go 语言更多,但我也仍然会用 Rust 编写一些工具,并在 WebAssembly 中使用 Rust。
参考资料
[1]Web archive: https://web.archive.org/web/20170916192117/https://github.com/golang/go/wiki/MinimumRequirements
[2]The Rust Programming Language: https://doc.rust-lang.org/stable/book/
[3]Rust By Example: https://doc.rust-lang.org/rust-by-example/
[4]Rust std lib docs: https://doc.rust-lang.org/std/index.html
[5]Microsoft Learn Rust path: https://learn.microsoft.com/en-us/training/paths/rust-first-steps/
[6]Rust Crash Course: https://www.youtube.com/watch?v=zF34dRivLOw&utm_source=blog.moelove.info&utm_medium=content
[7]Rust Tutorial: https://www.youtube.com/watch?v=T_KrYLW4jw8&list=PLzMcBGfZo4-nyLTlSRBvo0zjSnCnqjHYQ&utm_source=blog.moelove.info&utm_medium=content
[8]Rust for Beginners: https://www.youtube.com/playlist?list=PLlrxD0HtieHjbTjrchBwOVks_sr8EVW1x&utm_source=blog.moelove.info&utm_medium=content