
本文整理自 CloudWeGo 開源一周年技術(shù)沙龍活動(dòng)中字節(jié)跳動(dòng)基礎(chǔ)架構(gòu)服務(wù)框架資深研發(fā)工程師吳迪的演講分享,技術(shù)沙龍主題為《字節(jié)高性能開源微服務(wù)框架:CloudWeGo》。
本文將從以下三個(gè)方面介紹 CloudWeGo 開源的國(guó)內(nèi)首個(gè) Rust RPC 框架 Volo:
- CloudWeGo 選擇 Rust 語(yǔ)言進(jìn)行探索的原因;
 - 創(chuàng)建 RPC 框架 Volo 的原因;
 - Rust 語(yǔ)言和 Go 語(yǔ)言如何選擇。??
 
1. CloudWeGo 選擇 Rust 語(yǔ)言進(jìn)行探索的原因
CloudWeGo 正式官宣新一代 Rust RPC 框架 Volo 開源!很多朋友會(huì)有疑問(wèn),CloudWeGo 為什么會(huì)選擇 Rust 這門語(yǔ)言進(jìn)行探索呢?本文首先介紹一下其中的原因。
Volo 開源官宣:https://mp.weixin.qq.com/s/XcceLyKxWOVtoMIJBuwXWQ
1.1 Go 的代價(jià)
深度優(yōu)化困難
Volo 早期的團(tuán)隊(duì)成員來(lái)自于 Kitex 項(xiàng)目(CloudWeGo 開源的 Golang 微服務(wù) RPC 框架)。當(dāng)時(shí)我們投入了大量的時(shí)間和精力優(yōu)化 Kitex 以及其他相關(guān)基礎(chǔ)庫(kù)的性能,最終卻發(fā)現(xiàn)實(shí)現(xiàn) Go 的深度優(yōu)化有些困難。我們僅僅可以做一些算法層面和實(shí)現(xiàn)層面的優(yōu)化,如果想往下繼續(xù)做其他層面的優(yōu)化,比如指令層面的優(yōu)化,是很難以低成本的方式實(shí)現(xiàn)的。而且在大多數(shù)情況下很多優(yōu)化是要和 runtime 以及編譯器作斗爭(zhēng)的。
工具鏈和包管理不夠成熟
例如,使用 Kitex 框架時(shí)需要先使用對(duì)應(yīng)的 Kitex 工具生成代碼,才能正常編譯使用。雖然這種情況可能在 Frugal 工具成熟之后有所改善,但是在 IDL 有更新的情況下,還是需要使用 Kitex 重新生成對(duì)應(yīng)的結(jié)構(gòu)體。這個(gè)問(wèn)題并不是 Kitex 的問(wèn)題,而是 Go 語(yǔ)言本身的問(wèn)題,Go 語(yǔ)言在編譯時(shí)沒有提供類似的能力。
抽象能力較弱
Go 語(yǔ)言的抽象能力是比較弱的,而且 Go 語(yǔ)言里面的抽象并不是零成本抽象,而是有代價(jià)的抽象。
那么使用 Go 語(yǔ)言需要付出的三個(gè)代價(jià)具體應(yīng)該如何理解呢?下面進(jìn)行具體分析。
1.1.1 深度優(yōu)化困難
如圖所示,這是 Kitex 項(xiàng)目生成代碼的簡(jiǎn)單示例。這兩段代碼的目的是在解析出錯(cuò)的時(shí)候,把一些信息返回給上層。在 Kitex 新版本代碼公開之后,業(yè)務(wù)團(tuán)隊(duì)同學(xué)反映他們線上序列化和反序列化這部分的性能相差了 20%,經(jīng)排查之后,我們發(fā)現(xiàn)了這個(gè)改動(dòng)。

Kitex 新版本的代碼

Kitex 舊版本的代碼
這個(gè)改動(dòng)的本意是希望能給客戶提供更多錯(cuò)誤上下文的信息。但是它帶來(lái)了什么問(wèn)題呢?如下圖,它把匯編代碼直接一對(duì)一地生成到主流程之中,也就是說(shuō) Go 語(yǔ)言的編譯器會(huì)逐行逐句地進(jìn)行翻譯,并且不會(huì)做重排。

那么這會(huì)帶來(lái)什么問(wèn)題呢?由于我們主流程中的代碼與正常流程相比變多了,所以我們重點(diǎn)關(guān)注一下 L1-icache-load-misses? 這一行,新版本的代碼比舊版本的代碼在 L1 指令 cache? 層面 cache-misses 高出 20%,這也就是我們的代碼效率降低 20% 的原因。那么我們是如何解決這個(gè)問(wèn)題的呢?
我們的解決方案如下圖所示。在 err != nil? 的情況下,直接手動(dòng)加一條 goto? 語(yǔ)句,把所有錯(cuò)誤處理這部分的代碼放到函數(shù)末尾,即 return? 之后。這相當(dāng)于在編譯器沒有實(shí)現(xiàn)指令重排的情況下,用人工方式做一次指令重排。最后優(yōu)化的效果是非常明顯的,可以看到 cache-misses 比之前的那一次還要降低 25%。

上述例子只是使用 Go 語(yǔ)言時(shí)在做深度優(yōu)化方面遇到的難題。在抽象能力方面,使用 Go 語(yǔ)言也會(huì)遇到一些困難。
1.1.2 零成本抽象(Zero-Cost Abstraction)
什么是零成本抽象呢?使用 C++ 和 Rust 的同學(xué)對(duì)這個(gè)概念可能有所了解。零成本抽象是指我們不需要對(duì)沒有使用的功能付出編譯和運(yùn)行的開銷,也就是用戶不需要給沒有使用的東西付費(fèi),對(duì)應(yīng)地,如果用戶對(duì)于已經(jīng)使用的東西也沒有再繼續(xù)優(yōu)化的空間,因?yàn)樗呀?jīng)默認(rèn)提供了最佳實(shí)踐??偨Y(jié)如下:
- 不用的東西,不需要為之付出代價(jià);
 - 用到的東西,你也不可能做得更好。
 
那么為什么說(shuō) Go 語(yǔ)言里面沒有零成本抽象呢?以 Thrift 編解碼為例,我們最開始使用的是 Apache Thrift,它為了支持多種不同 Protocol、Transport 組合,抽象出了 TProtocol Interface、TTransport Interface,但 Kitex 直接依賴具體的 BinaryProtocal 的實(shí)現(xiàn)(struct)??梢栽囅?,Apache Thrift 這么做的代價(jià)是什么呢?這就是 Go 里面 Interface 帶來(lái)的代價(jià)。
Go 里面 Interface 是動(dòng)態(tài)分發(fā)的,也就是運(yùn)行時(shí)通過(guò)類型元數(shù)據(jù)和指針去動(dòng)態(tài)調(diào)用所需方法,它會(huì)在運(yùn)行時(shí)多做一次內(nèi)存尋址。但這并不是最關(guān)鍵的,最關(guān)鍵的是它會(huì)使得編譯器沒有辦法 inline 以及沒有辦法做很多優(yōu)化。一般比較注重性能的語(yǔ)言都會(huì)同時(shí)提供靜態(tài)分發(fā)和動(dòng)態(tài)分發(fā)兩種方式的抽象能力,但是 Go 語(yǔ)言只提供了 Interface 動(dòng)態(tài)分發(fā)能力,也就可以理解為在 Go 語(yǔ)言中抽象和性能是不可兼得的,這也就是 Go 語(yǔ)言抽象能力比較弱的原因。
1.2 Sonic
Sonic 是 CloudWeGo 開源的一個(gè) JSON 庫(kù),這個(gè)庫(kù)有很多 CloudWeGo 的用戶都使用過(guò)。最初這個(gè)庫(kù)組成部分如下圖所示,有 2/3 的代碼都是 Assembly 匯編。

在 Sonic 庫(kù)中僅有的 27% 的 Go 源代碼如下圖所示。雖然它被統(tǒng)計(jì)到了 Go 代碼中,但實(shí)際上是匯編代碼。所以我們可以總結(jié)出,世界上最快的 Go 語(yǔ)言程序大概就是用匯編代碼寫就的。

1.3 性能最好的 Go JSON 庫(kù)
盡管 Sonic 里面采用了各種黑科技,甚至有 2/3 的代碼都是經(jīng)過(guò)人工精調(diào)的匯編代碼,但是 Sonic 的綜合性能還是不如 Rust 最通用的 Serde JSON 庫(kù)。如圖所示,綠色柱狀圖代表 Serde JSON 庫(kù),藍(lán)色柱狀圖代表 Sonic 庫(kù)。根據(jù)這個(gè) Benchmark,即使是和 C、C++ 的庫(kù)相比,用 Rust 語(yǔ)言編寫的這個(gè)庫(kù)在各方面綜合表現(xiàn)也是最佳的。
試想,又有多少 Go 組件能夠得到如此大量的人力投入從而進(jìn)行深度優(yōu)化呢?這只是一個(gè)例子,其實(shí)我們之前在 Kitex 中的很多優(yōu)化也是要和編譯器以及 runtime 作斗爭(zhēng)的。因此我們認(rèn)識(shí)到在 Go 語(yǔ)言中想做深度優(yōu)化是非常困難的。

1.4 關(guān)于 Rust
我們?yōu)槭裁匆x擇 Rust 這門語(yǔ)言呢?在解答這個(gè)問(wèn)題之前,要先了解這門語(yǔ)言。所以先介紹一下 Rust 語(yǔ)言的發(fā)展歷史。
1.4.1 Rust 歷史
Rust 語(yǔ)言由 Graydon Hoare 私人研發(fā),他是 Mozilla 做編程語(yǔ)言的工程師,專門給語(yǔ)言開發(fā)編譯器和工具集。當(dāng)時(shí) Mozilla 要開發(fā) Servo 引擎,想要保證安全的同時(shí)又能擁有高性能,于是就選擇了 Rust 語(yǔ)言。2010 - 2015 年期間,Rust 是有 GC 的,后來(lái)社區(qū)一致表示支持 Rust 必須要有高性能,所以 GC 被取締。2015 年,Rust 發(fā)布 1.0 版本,這也表示正式官宣 Rust 的穩(wěn)定性。
Rust 是以三年為單位進(jìn)行社區(qū)規(guī)劃和迭代的。2015 - 2018 年,Rust 達(dá)成了生產(chǎn)力的承諾,也就是它的工具文檔還有編譯器變得更加智能,也對(duì)開發(fā)者更加友好了。2018 - 2021 年,Rust 做了更多異步生態(tài)的完善。之前的 Rust 是沒有異步生態(tài)的,但是自 2018 年開始,它正式引入了異步功能。

1.4.2 Rust 2024
2021 - 2024 年,Rust 有一個(gè) 2024 規(guī)劃,主題叫做 Scaling Enpowerment(擴(kuò)展授權(quán))。之所以取這個(gè)名字,是因?yàn)?Rust 有一個(gè)目標(biāo)——“empower everyone to build reliable and efficient software”。Rust 最關(guān)注也是大家經(jīng)常詬病的一點(diǎn),就是 Rust 的整個(gè)學(xué)習(xí)曲線非常陡峭,所以在這個(gè)規(guī)劃中寫道 “Flatten the learning curve”。

1.4.3 Rust 三大優(yōu)勢(shì)
在 2022 年,很多開源項(xiàng)目已經(jīng)呈現(xiàn)爆炸式增長(zhǎng)。我們了解到 Rust 這門語(yǔ)言后,發(fā)現(xiàn)它有三大非常重要的優(yōu)勢(shì):第一是高性能;第二是很強(qiáng)的安全性;第三是協(xié)作方便。因此我們想嘗試在服務(wù)端使用 Rust 語(yǔ)言開發(fā)微服務(wù),以此解決我們面臨的一些性能上的問(wèn)題。
性能
很多用戶都對(duì)性能有很高的要求,也想知道 Rust 的性能如何。下圖是各語(yǔ)言的 Benchmark 對(duì)比結(jié)果,可以看出 Rust 的性能是非常優(yōu)秀的,遠(yuǎn)超過(guò) Go 語(yǔ)言,甚至比 C++ 的性能更好。
當(dāng)然我們要著重說(shuō)明,這個(gè) Benchmark 要求所有語(yǔ)言必須使用相同的算法,并且不得經(jīng)過(guò)額外優(yōu)化。畢竟如果都用匯編代碼寫,其實(shí)各語(yǔ)言性能相差無(wú)幾。但是在真正的開發(fā)過(guò)程中,又有多少代碼能夠經(jīng)過(guò)那么大量的人工精細(xì)優(yōu)化呢?另外,有人可能會(huì)對(duì) Rust 的性能比 C 和 C++ 更優(yōu)秀產(chǎn)生質(zhì)疑,其實(shí)這也是因?yàn)?Rust 對(duì)于程序員的輸入要求得更加嚴(yán)格,所以編譯器可以做更進(jìn)一步的優(yōu)化。

安全性
因?yàn)樵?Rust 語(yǔ)言的安全性方面可查閱到大量資料,因此不再過(guò)多贅述。只闡述一個(gè)重要結(jié)論:Rust 1.0 之后,在非 Unsafe 代碼中是不可能出現(xiàn)內(nèi)存安全問(wèn)題的。這個(gè)結(jié)論是通過(guò)數(shù)學(xué)證明過(guò)的,因此非??煽?。我們應(yīng)該如何理解這個(gè)結(jié)論呢?可以從它的推論入手,即:一切內(nèi)存 / 并發(fā)安全問(wèn)題,都是 unsafe 代碼導(dǎo)致的。也就是如果真的出現(xiàn)安全問(wèn)題,我們可以限制在一個(gè)非常小的范圍內(nèi)進(jìn)行排查。因?yàn)楫吘菇^大多數(shù)的 Rust 語(yǔ)言代碼都是 Safe Rust,而不是 Unsafe Rust。
協(xié)作
Rust 是一門真正通過(guò)工程實(shí)踐形成的語(yǔ)言,它有非常智能的編譯器、完善的文檔、集群的工具鏈和成熟的包管理,因此 Rust 非常適合協(xié)作。我們?cè)谑褂脮r(shí)可以專注于邏輯功能的實(shí)現(xiàn),而不用擔(dān)心內(nèi)存安全和并發(fā)安全的問(wèn)題等等。還有非常重要的一點(diǎn)就是可以限制別人的代碼,因?yàn)槿绻麆e人的代碼有內(nèi)存安全問(wèn)題或并發(fā)安全問(wèn)題,將無(wú)法進(jìn)行編譯。所以在做 Code Review 時(shí),我們只需關(guān)注邏輯上的功能正確性就可以,因?yàn)橹灰軌蛲ㄟ^(guò)編譯提交上來(lái)的代碼,安全性是不必?fù)?dān)心的。這雖然是 Rust 語(yǔ)言的優(yōu)點(diǎn),但也給使用者帶來(lái)一些不便之處。我們常聽說(shuō) Rust 開發(fā)者很難,也正是因?yàn)榫幾g。
1.4.4 Rust 的影響力
如下圖,Rust 已經(jīng)連續(xù)七年位居 Stack Overflow 最受開發(fā)者喜愛的編程語(yǔ)言榜榜首。此外,有一個(gè)非常重量級(jí)的項(xiàng)目叫做 “Rust for Linux”,除了 C 語(yǔ)言之外,Rust 是 Linux 內(nèi)核迄今為止接受的唯一語(yǔ)言。這些成績(jī)足以看出 Rust 在開源業(yè)界的重量級(jí)和影響力。

2. 創(chuàng)建 RPC 框架 Volo 的原因
明確了 CloudWeGo 選擇 Rust 語(yǔ)言的原因以及 Rust 的優(yōu)勢(shì),我也闡述一下創(chuàng)造 Volo 框架的原因以及 Volo 的特點(diǎn)。
2.1 生態(tài)現(xiàn)狀
創(chuàng)造 Volo 框架與當(dāng)時(shí)的生態(tài)情況是有關(guān)的。我們當(dāng)時(shí)調(diào)研過(guò)整個(gè)社區(qū)的生態(tài),發(fā)現(xiàn)沒有生產(chǎn)可用的 Async Thrift 實(shí)現(xiàn)。哪怕是社區(qū)中最成熟的 Tonic 框架,它的服務(wù)治理功能也是比較弱的,而且易用性也不夠強(qiáng)。更重要的是當(dāng)時(shí)在 Rust 語(yǔ)言社區(qū),還沒有基于 Generic Associated Type(GAT,Rust 語(yǔ)言最新的?個(gè)重量級(jí) Feature)和 Type Alias Impl Trait(TAIT,另?個(gè)重量級(jí) Feature)的易用性強(qiáng)的抽象。
2.2 易用性
為什么單獨(dú)說(shuō)明 GAT 和 TAIT 這兩個(gè)特性呢?按照 Rust 官方團(tuán)隊(duì)的說(shuō)法,這是自 Rust 1.0 以來(lái)語(yǔ)言層面和 Type System 層面最大的變化。舉例簡(jiǎn)單說(shuō)明,下圖是一個(gè)現(xiàn)有的社區(qū)方案,代碼是沒有使用 GAT 和 TAIT 的超時(shí)中間件的編寫,我們可以發(fā)現(xiàn)如果要保證性能不受損耗,需要編寫大量代碼。

而在 Volo 框架中,因?yàn)椴捎昧?GAT 和 TAIT 這兩個(gè)特性,編寫代碼如下圖所示。我們可以明顯對(duì)比出代碼量和易用性方面的差距是非常明顯的。Rust 以難學(xué)難用而聞名,我們希望盡可能地降低用戶使用 Volo 框架和 Rust 語(yǔ)言編寫微服務(wù)的難度,提供給用戶最符合人體工程學(xué)和直覺的編碼體驗(yàn),因此我們把框架易用性作為重要目標(biāo)之一。只有讓大家真正地使用 Volo,Volo 才能體現(xiàn)它的價(jià)值。所以 Volo 框架基于 GAT 和 TAIT 特性,大大提升了用戶編寫中間件的便利程度。

除此之外,我們提供了 Volo 命令行工具生成默認(rèn) Layout,并且 Volo 的命令行工具提供 IDL 管理的能力,這在業(yè)界是首例。我們還提供了過(guò)程宏等能夠再度降低 Service 編寫難度的功能。當(dāng)然還有很多其他的精心設(shè)計(jì),比如很多 API 都是盡量以最符合人體工程學(xué)的方式給出的,也可以避免誤用。
2.3 擴(kuò)展性
基于 Service 的抽象
受益于 Rust 強(qiáng)大的表達(dá)和抽象能力,開發(fā)者可以基于非常靈活的 Service 抽象,用統(tǒng)一的形式對(duì) RPC 的元信息請(qǐng)求和響應(yīng)做一些處理,比如服務(wù)發(fā)現(xiàn)、負(fù)載均衡等服務(wù)治理功能都是直接實(shí)現(xiàn) Service 即可。

基于RPC元信息的控制
另外,在我們的框架設(shè)計(jì)中,所有框架行為都是受到 RPC 元信息控制的。因此我們只要在 Service 中對(duì) RPC 元信息進(jìn)行修改,就能直接控制框架的行為,從而實(shí)現(xiàn)所需的功能。
下圖是 Volo 自帶的負(fù)載均衡中間件實(shí)現(xiàn)中最關(guān)鍵的一部分,即紅色線框圈出的代碼。只要把 Load Balance 選出來(lái)的地址放到 RPC 元信息中就可以,其他代碼可以直接忽視掉。

2.4 性能
如果過(guò)多談?wù)摽蚣艿男阅軐?duì)比,容易引戰(zhàn)。但是基于 Rust 語(yǔ)言的性能優(yōu)勢(shì)以及 CloudWeGo 團(tuán)隊(duì)對(duì)于極致性能的追求,我們可以預(yù)想到 Volo 的性能也是非常高的。
如果把 Volo 和 Kitex 進(jìn)行跨語(yǔ)言的對(duì)比也是不太公平的,但是因?yàn)楹芏嘤脩舳缄P(guān)注性能數(shù)據(jù),為了讓使用者對(duì) Volo 框架的性能有大致的了解,我們只給出比較簡(jiǎn)單的性能數(shù)據(jù)。在與 Kitex 相同的測(cè)試條件(限制 4C)下,Volo 極限 QPS 為 35W。同時(shí),我們內(nèi)部正在驗(yàn)證基于 Monoio(CloudWeGo 開源的 Rust Async Runtime)的版本,極限 QPS 可以達(dá)到 44W。
當(dāng)然還有很多其他的性能指標(biāo),比如響應(yīng)時(shí)間也是非常影響用戶體驗(yàn)的。所以除了 Benchmark,我們選取了由 Go 遷移到 Volo 框架的兩個(gè)業(yè)務(wù),呈現(xiàn)真實(shí)的業(yè)務(wù)落地收益。
業(yè)務(wù) A(Proxy 類) 。A 業(yè)務(wù)的 IO 比較多,遷移到 Volo 框架后的各方面數(shù)據(jù)如下:
- CPU Usage 630% -> 380%
 - MEM 9GB -> 2GB
 - P99 150-200ms -> 20-35ms
 - AVG 4-5ms -> 1.5ms
 
可以看出不論是 CPU、內(nèi)存還是延時(shí)的指標(biāo),都有非常明顯的提升。下圖中間紅線代表 Volo 上線的時(shí)間,也就是紅線左側(cè)這一部分是 Go 的指標(biāo),紅線右側(cè)是 Rust 的指標(biāo),左右對(duì)比可以更直觀看出 Volo 框架給業(yè)務(wù) A 帶來(lái)的收益。

業(yè)務(wù) B(有大量業(yè)務(wù)邏輯) 。業(yè)務(wù) B 是一個(gè)計(jì)算密集型的業(yè)務(wù),使用 Volo 框架后 CPU 400% -> 130%。因此在計(jì)算密集型的業(yè)務(wù)中,CPU 的提升更加明顯。
2.5 相關(guān)生態(tài)
隨著 Volo 框架開源,一起開源的所有生態(tài)如下:
- Volo 是 RPC 框架的名字,包含了 Volo-Thrift 和 Volo-gRPC 兩部分。
 - Volo-rs 組織:Volo 的相關(guān)生態(tài)。
 - Pilota:Volo 使用的 Thrift 與 Protobuf 編譯器及編解碼的純 Rust 實(shí)現(xiàn)(不依賴 protoc)。
 - Motore:Volo 參考 Tower 設(shè)計(jì)的,使用了 GAT 和 TAIT 的 middleware 抽象層。
 - Metainfo:Volo 用于進(jìn)行元信息透?jìng)鞯慕M件,定義了一套元信息透?jìng)鞯臉?biāo)準(zhǔn)。
 
全景圖如下:

2.6 倉(cāng)庫(kù)地址
以下是所有相關(guān)生態(tài)的倉(cāng)庫(kù)地址。歡迎大家來(lái)提 Issue 或 PR,一起共建 Volo!
- Volo:https://github.com/cloudwego/volo
 - Volo-rs:https://github.com/volo-rs
 - Pilota:https://github.com/cloudwego/pilota
 - Motore:https://github.com/cloudwego/motore
 - Metainfo:https://github.com/cloudwego/metainfo
 
3. Rust 語(yǔ)言和 Go 語(yǔ)言如何選擇
了解 Volo 框架后,關(guān)于 Rust 語(yǔ)言和 Go 如何選擇的問(wèn)題,我有一些主觀的建議和想法。
3.1 和 C++、Go 對(duì)比
如果 Go 的服務(wù)想用另一種語(yǔ)言重寫,目前還是 Rust 語(yǔ)言和 C++ 可選性高一些,因此我將這三種語(yǔ)言進(jìn)行對(duì)比,以期為面臨選擇編程語(yǔ)言的用戶提供一些參考。

在學(xué)習(xí)難度方面,Rust 語(yǔ)言和 C++ 學(xué)習(xí)難度比較高,而 Go 語(yǔ)言的學(xué)習(xí)難度比較低。
在性能方面,Rust 語(yǔ)言和 C++ 的性能比較高。我給 Go 語(yǔ)言的性能評(píng)級(jí)為中等,畢竟和 Python 這些服務(wù)相比,Go 語(yǔ)言還是要強(qiáng)很多的。
在安全性方面,C++ 的安全性比較低,Go 語(yǔ)言安全性中等,Rust 語(yǔ)言安全性比較高。因?yàn)?Go 語(yǔ)言 雖然能夠通過(guò) GC 防住一些內(nèi)存安全的問(wèn)題,但是它沒有辦法防住類似 Data Race 這種并發(fā)安全的問(wèn)題,而且大多數(shù)時(shí)候這類問(wèn)題其實(shí)很難排查。Rust 能夠做到可防可控,應(yīng)防盡防,只要有內(nèi)存安全問(wèn)題或并發(fā)安全問(wèn)題,都無(wú)法成功編譯。
在協(xié)作方面,Rust 語(yǔ)言的協(xié)作能力比較高,Go 語(yǔ)言和 C++ 的協(xié)作等級(jí)是中等。首先,C++ 沒有官方提供的包管理工具,它必須借助第三方社區(qū)提供的包管理工具,但是不同的項(xiàng)目使用的包管理工具可能是不一樣的,所以這是對(duì)用戶來(lái)說(shuō)非常不便的;其次,在開發(fā)者可以保證自己的代碼沒有 Bug、符合最佳實(shí)踐的情況下,還是不可避免地會(huì)和一些第三方的庫(kù)以及比較老舊社區(qū)一流的庫(kù)產(chǎn)生交集,并且產(chǎn)生混用的情形;最后,如果涉及到大型項(xiàng)目,需要團(tuán)隊(duì)協(xié)作開發(fā),我們無(wú)法保證團(tuán)隊(duì)中其他人寫出的代碼也不存在內(nèi)存安全問(wèn)題。至于 Go 語(yǔ)言,它的編譯時(shí)及工具鏈的能力相對(duì)來(lái)說(shuō)比較弱,因此也定級(jí)為中等。
在特性和使用成本方面,用戶應(yīng)該都有所了解,不再過(guò)多贅述。從使用成本上來(lái)講,我的評(píng)級(jí)為給 C++ 為高使用成本,Go 語(yǔ)言和 Rust 語(yǔ)言的使用成本是中等。C++ 的業(yè)務(wù)上線之后經(jīng)常出狀況,而且排查問(wèn)題困難是很常見的情況。而使用 Go 語(yǔ)言做一些通用的編程是可以的,但是一旦涉及到定制化的需求在實(shí)現(xiàn)上就有一定的困難,比如需要根據(jù)不同的平臺(tái)系統(tǒng)做系統(tǒng)級(jí)編程,使用 Go 語(yǔ)言做起來(lái)就非常麻煩。語(yǔ)言只是工具,我們還是要根據(jù)不同的場(chǎng)景選用更為合適的語(yǔ)言。
那么 Go 語(yǔ)言和 Rust 語(yǔ)言的使用成本為什么是中等呢?因?yàn)槲覀儾荒苤魂P(guān)注編寫代碼的效率,還要考慮運(yùn)維和 Debug 的成本。Go 語(yǔ)言可能也會(huì)產(chǎn)生 Panic,我們內(nèi)部也經(jīng)常會(huì)有一些并發(fā)的問(wèn)題,然后需要不斷地排查。而 Rust 語(yǔ)言前置了這部分成本,相比于其他語(yǔ)言框架在上線之后測(cè)試、保證穩(wěn)定性,我們把這部分的時(shí)間精力用在了開發(fā)期間,這樣也避免了線上事故帶來(lái)的損失。因此我給 Go 語(yǔ)言和 Rust 語(yǔ)言評(píng)定的使用成本是中等。
3.2 Rust & Go
如果將 Rust 語(yǔ)言和 Go 語(yǔ)言單獨(dú)做對(duì)比,我們應(yīng)該如何解讀它們呢?這是一個(gè)非常經(jīng)典的問(wèn)題??梢試L試從以下四方面考慮:
合作關(guān)系,取長(zhǎng)補(bǔ)短
我們團(tuán)隊(duì)認(rèn)為其實(shí)二者并不是對(duì)立關(guān)系,而是合作關(guān)系,它們是取長(zhǎng)補(bǔ)短的。畢竟語(yǔ)言只是工具,很多時(shí)候我們只是需要一個(gè)更加得心應(yīng)手的工具而已。
(性能 >> 開發(fā)效率) || (安全性 >> 開發(fā)效率) ->Rust
對(duì)于需要極致性能,重計(jì)算的應(yīng)用,以及需要穩(wěn)定性并能接受一定開發(fā)速度損失的應(yīng)用,推薦使用 Rust,Rust 在極致性能優(yōu)化和安全性上的優(yōu)勢(shì)可以在這類應(yīng)用中得以發(fā)揮。
迭代速度要求高 -> Go
對(duì)于性能不敏感的應(yīng)用、重 IO 的應(yīng)用以及需要快速開發(fā)快速迭代勝過(guò)穩(wěn)定性的應(yīng)用,推薦使用 Go 語(yǔ)言,這種應(yīng)用使用 Rust 并不會(huì)帶來(lái)明顯的收益。
考慮團(tuán)隊(duì)技術(shù)儲(chǔ)備和人才儲(chǔ)備
當(dāng)然,還有一個(gè)很重要的考慮因素,是團(tuán)隊(duì)現(xiàn)有的技術(shù)棧,即技術(shù)儲(chǔ)備和人才儲(chǔ)備。
4. 小結(jié)
希望以上內(nèi)容能讓大家初步了解 Volo 以及相關(guān)的生態(tài)。目前 Volo 還處于早期發(fā)展階段,歡迎各位感興趣的同學(xué)加入我們,共同建設(shè) CloudWeGo 以及 Rust 開源社區(qū)。我們誠(chéng)心期待更多開發(fā)者加入,也期待 Volo 能夠助力越來(lái)越多的企業(yè)快速構(gòu)建云原生架構(gòu)。















 
 
 












 
 
 
 