继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

初创企业使用 Rust:一则警示故事

BIG阳
关注TA
已关注
手记 429
粉丝 70
获赞 457

不过,对于某些任务来说,Rust 还是真的挺不错的。但是,如果你打算为一家需要快速迭代的初创公司工作的话,最好先仔细考虑一下。

这篇文章中的所有艺术作品都是由DALL-E生成的。

我在犹豫是否写这篇帖子,因为我并不想引发关于编程语言的大规模争论。(为了避免引起争议,先说一句,Visual Basic 是有史以来最好的语言!)但是,很多人问我关于 Rust 的经验,他们是否应该在项目中使用 Rust。因此,我想分享一些在初创公司中使用 Rust 的优缺点,在这种环境中快速行动和扩大团队规模非常重要。

我想明确一点,我确实认为 Rust 在某些方面很出色,但并不是说它在所有方面都完美。这篇文章并不是要讨论 Rust 是一种糟糕的语言。不过,我想讨论的是,使用 Rust 几乎肯定会带来一定的生产力损失,这对那些需要快速发展的团队来说可能是一个重要因素。仔细权衡这种速度损失是否值得你们公司和产品从 Rust 中获得的好处。

首先我要说的是,Rust 在它被设计的领域做得非常好。如果你的项目需要 Rust 的这些特点(一种高性能、强类型、无垃圾回收的系统语言),那么 Rust 是一个很好的选择。但是我认为 Rust 经常被用在并不那么适合的场合,团队为此承受了额外的复杂性和开销,却并没有得到多少好处。

我在一家之前的初创公司使用 Rust 工作了超过两年的时间。这个项目是一个基于云的 SaaS 产品,基本上就是个常规的 CRUD 应用程序。它由一组微服务构成,这些微服务在数据库前面提供了 REST 和 gRPC API 接口,还有一些其他后端微服务(这些服务是用 Rust 和 Python 组合实现的)。公司创始人中有几位 Rust 专家,因此项目主要使用了 Rust。随着时间推移,我们团队大幅扩张(工程师人数增加了近 10 倍),代码库的规模和复杂性也大幅增加。

随着团队和代码库的增长,我感觉随着时间的推移,我们继续使用 Rust 所付出的代价变得越来越沉重。开发进度有时变得缓慢,推出新功能所需的时间比预期要长,团队也确实感受到了早期选择 Rust 给生产力带来的明显损失。从长远来看,将代码重写成另一种语言会使开发更加灵活并加快交付时间,但找到时间进行重大重写工作会极其困难。所以我们只能继续使用 Rust,除非我们决定下决心重写大量代码。

Rust 应该是自从有了切片面包以来最棒的,但它对我们来说似乎用起来不太顺手。

学习 Rust 的难度很大。

在我的职业生涯中,我工作过几十种语言,除了少数例外,大多数现代编程语言(如C++、Go、Python、Java等)在基本概念上都很相似。每种语言都有所不同,但通常只需学习一些关键模式,就可以很快地变得高效。然而,对于Rust来说,你需要学习全新的概念和思维方式——比如生命周期、所有权和借用检查器。这些概念对于大多数使用其他常见语言的程序员来说并不熟悉,甚至对有经验的程序员来说也有相当陡峭的学习曲线。

当然,其中一些所谓的“新”想法实际上已经在其他语言中存在——尤其如函数式语言——但Rust将这些想法带入了主流语言环境,因此对许多Rust新手来说会感到新奇。

尽管我和团队中的许多成员(包括我自己在内)是我在合作过的最聪明且最有经验的开发者,我们在理解 Rust 中某些事情的标准做法、如何解读编译器经常晦涩的错误信息,以及如何理解关键库的工作原理上还是遇到了很大的困难(详见下文)。我们每周都会组织“学习 Rust”的团队会议,分享知识和经验。这大大影响了团队的生产力和士气,因为大家感觉开发进度缓慢。

作为比较,我的一个团队在谷歌是最早完全从 C++ 切换到 Go 的团队之一,大约两周后,这些十几人的团队成员就已经相当熟练地开始用 Go 编码了。而在使用 Rust 时,即使经过了几个月每天使用这种语言之后,大多数人仍然感觉自己对 Rust 不够熟练。很多开发者告诉我,他们经常因为自己的特性实现所需时间比预期长而感到尴尬,并且觉得花了太多时间来掌握 Rust。

还有其他办法可以解决 Rust 尝试解决的问题。

如上所述,我们正在构建的服务是一个简单的 CRUD 应用程序。在整个系统的生命周期内,负载预计保持在这个水平,即每秒不超过几个查询。该服务是一个前端,后面是一个复杂的、可能运行数小时的数据处理管道,因此该服务本身并不预期成为性能瓶颈。我们并不担心像 Python 这样的传统语言无法提供良好的性能。没有其他特殊的安全或并发需求,除了任何面向 Web 的服务所需的一般需求。我们选择使用 Rust 的唯一原因是该系统的初始作者是 Rust 专家,而不是因为它并不特别适合构建这种类型的服务。

Rust 的设计哲学是将安全性置于开发者生产力之上。 在很多情况下,比如构建操作系统内核或对内存有限制的嵌入式系统时,这样的权衡是合理的,但我认为这并不是在所有情况下都是正确的选择,尤其是在初创公司,速度至关重要时。作为实用主义者,我宁愿团队成员花时间调试 Python 或 Go 中偶尔出现的内存泄漏或类型错误,也不愿因使用旨在完全避免这些问题的语言而导致整个团队生产效率降低到原来的四分之一。

正如我之前提到的,我所在的谷歌团队建立了一个完全用 Go 语言开发的服务,随着时间的推移,该服务支持的用户数超过了 8 亿,并且其峰值请求量大约是谷歌搜索峰值的四倍。在我的记忆中,因为 Go 的类型系统或垃圾回收器而遇到的问题可以用一只手来数。基本上,Rust 意在避免的问题可以通过其他方法解决——通过良好的测试、代码检查、代码审查和监控。当然,并非所有软件项目都有这种奢侈,因此可以想象,在这些情况下,Rust 可能是一个更好的选择。

找 Rust 开发人员可不容易。

在我在这家公司工作期间,我们招聘了大量的员工,但加入工程团队的这六七十人中,只有两三个之前有过Rust的经验。这并不是因为我们没有努力寻找Rust开发者——只是这样的开发者非常稀缺。(同样的,我们也比较谨慎于招聘那些只希望用Rust编码的人,因为在创业环境中,语言和其他技术的选择需要灵活处理,这样的期望可能不太实际。)随着时间推移,Rust变得越来越流行,这种Rust开发人才短缺的情况会有所改善,但假设你能招聘到已经掌握Rust的人才来构建项目,似乎还是有些风险。

另一个次要因素是,使用 Rust 很可能造成团队内部懂 Rust 的人和不懂 Rust 的人之间的分裂。因为我们选择了这种“晦涩难懂”的编程语言来构建这项服务,公司里的其他工程师本可以帮忙构建特性、调试生产问题等,但由于他们对 Rust 代码库一头雾水,所以基本上帮不上忙。这种工程团队成员之间的不可替代性在你试图快速推进并充分利用每个人的优势时,可能会成为一个真正的负担。据我经验,人们通常在 C++ 和 Python 这样的语言之间切换并不困难,但 Rust 既新又复杂,成了团队合作的绊脚石。

目前库和文档还不够完善。

这是一个我希望会随着时间得到解决的问题,但与 Go 相比,Rust 的库和文档生态系统非常不成熟和完善。Go 在发布之前得到了谷歌内部一个专门团队的支持,因此其文档和库都相当完善。相比之下,Rust 总是给人一种正在进行中的感觉。许多流行库的文档都相当简陋,很多时候需要阅读给定库的 源代码 才能弄清楚如何使用它。这真不妙。

团队中的 Rust 支持者经常会说类似“异步/等待功能还很新”和“那个库的文档确实不够完善”这样的话,但这些缺点对团队影响很大。我们早期采纳 Actix 作为服务的 Web 框架,这显然是一个巨大的错误,导致我们在处理库中的深层 bug 和问题时,经历了很多痛苦和困扰,大家都感到很头疼。(公平地说,这已经是几年前的事了,也许现在情况有所改观。)

当然,这种不成熟并不只存在于 Rust 中,但它确实相当于你团队需支付的一种额外费用。无论核心语言的文档和教程有多好,如果你弄不清如何使用库,那意义就不大(除非你打算从零开始编写所有东西,当然)。

用 Rust 添加新功能特别难搞。

我不知道其他人的情况如何,但至少对我来说,在构建新功能时,我通常不会一开始就将所有数据类型、API和其他细节都规划好。我经常只是先写一些基本的代码,试图让一些基础的想法运作起来,并检查我的假设是否正确。用像Python这样的语言来做这个事情非常容易,因为你可以在类型和其他细节上比较随意,不必担心某些代码路径在你构思初始想法时是否已经出错。你可以在之后整理代码,修正类型错误并编写测试。

在 Rust 中,这种“草稿式的编程”非常困难,因为编译器会抱怨每一个没有通过类型或生命周期检查的东西——它正是被设计成这样工作的。当你需要构建最终的、生产就绪的实现时,这的确是有道理的,但当你试图拼凑一些东西来测试一个想法或搭建一个基本框架时,这简直让人头疼。unimplemented! 宏在某种程度上有所帮助,但仍然要求在编译之前,所有相关类型都必须通过整个调用栈的检查。

最让人头疼的是,当你需要改变一个关键接口的类型定义时,发现自己花了好几个小时去修改每个使用该类型的地方,试一试最初的方案是否可行。然后,当你意识到你需要再次更改它时,不得不重新做一遍所有这些修改。

Rust 擅长什么?

确实有一些我喜欢的Rust特性,我也希望能使其他语言拥有类似的特性。match语法很棒。OptionResultError这些特性非常强大,而?操作符则是一种处理错误的优雅方式。虽然其他语言中也有类似的特性,但Rust处理这些特性的方法尤为优雅。

我绝对会选择 Rust 来处理那些需要高性能和高安全性的项目。对于那些不太担心代码需要快速迭代,并且团队在迅速扩张的项目来说,我也不会有太大顾虑。对于个人项目或非常小的团队(比如2到3人),Rust 也完全没问题。Rust 是处理内核模块、固件、游戏引擎等的绝佳选择,在这些领域中,性能和安全性是最重要的。特别是在正式发布之前很难做彻底测试的情况下,Rust 也是很好的选择。

好了,现在我已经把Hacker News一半的读者激怒了,现在宣布我下一篇文章的主题也挺合适的:为什么nano是更好的文本编辑工具。下次聊!

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP