如果我正在編寫一個地理編碼器、一個路由引擎、一個實時消息平臺、一個數據庫或一個 CLI 工具,Rust 最合適。 但去年,我試圖用 Rust 寫一個傳統(tǒng)網站的純 API 服務,Rust 就不合適了。 Rust 有大量的 Web 服務框架、數據庫連接器和解析器。但搭建身份驗證服務方面只有非常低層次的組件。Node.js 有 passport.js,Rails 有 devise,Django 有開箱即用的身份驗證模型,在 Rust 中,你需要學習如何將共享 Vec 轉換到底層加密庫才能構建這個系統(tǒng)(譯者注,Vec 是一個動態(tài)數組,只會自動增長而不會自動收縮。區(qū)別于 Array,Vec 具有動態(tài)的添加和刪除元素的能力,并且能夠以 O(1) 的效率進行隨機訪問。Vec 的所有內容項都是生成在堆空間上的,可以輕易的將 Vec 移出一個棧而不用擔心內存拷貝影響執(zhí)行效率,畢竟只是拷貝棧上的指針)。有些庫試圖解決這個問題,比如 libreauth,但它才剛剛開始開發(fā)。還有很多類似的 Web 框架問題。 SDK 呢?在主流編程語言中,你可以通過一個官方庫來接入 Google 云服務、AWS 或 Stripe。這些官方庫大都很棒。例如,aws-sdk-js 和 Stripe 庫的設計和維護得非常好。 Rust 就不這樣,只有少許第三方庫,但以這些服務的開發(fā)速度,它們真的能夠提供高質量的體驗嗎? 有人會說好吧,X 編程語言太好了,你可以在周末自己寫一個 SDK!我必須回答,不。 Rust 的生態(tài)系統(tǒng)在其它領域非常豐富。用于構建 CLI、管理并發(fā)性、使用二進制數據和底層解析器的 crates 令人印象深刻,非常棒。 我一直在看 Nicholas Nethercote 的博客,描述了 Rust 團隊如何優(yōu)化編譯器,讓它更快! 但與其它編程語言相比,用它構建網站會很慢。它比編譯型編程語言 Go 慢得多,也比解釋型編程語言 JavaScript、Ruby 和 Python 等慢得多。 一旦代碼被編譯,一切就變得非常棒了!但在我的情況下,甚至基本 API 功能都不完整,一個不復雜的系統(tǒng)——居然花了 10 多分鐘來編譯。Google 代碼構建的硬件配置很差,每次都會超時,我啥都編譯不了。 只要不重建緩存依賴項,緩存就有意義。也許減少依賴會加快 Rust 項目編譯。但就像 serde,幾乎所有人都使用的 JSON 和其它序列化 / 反序列化程序占用了大量的編譯時間。我們是否應該用編譯速度更快但缺乏大量文檔和生態(tài)系統(tǒng)支持的東西來取代 serde?這種取舍非常糟糕。 Rust 讓你從代碼維度進行思考,這對系統(tǒng)編程來說非常重要。它讓你思考如何共享或復制內存,思考真實但不太可能的小概率事件,并確保妥善處理它們,幫你編寫各種各樣的高效代碼。 這些擔憂都是合理的,但是對于大多數 Web 應用程序來說,它們并不是最重要的關注點,以流行的慣性思考會導致不正確的假設。 就拿 Rust 的安全性來說吧。這是它宣傳語中的重要部分,這是絕對正確的:Rust 的承諾安全和底層兩者兼而有之——它可以在沒有垃圾收集器的情況下工作,同時防止基于內存的漏洞。當你讀到“安全”的時候,想想 Rust 的競爭對手 C 吧。C 語言中的代碼可以引用任意內存,很容易溢出和出錯。Rust 代碼可以和 C 代碼一樣快,但是可以保護內存訪問,而不需要垃圾收集器或某種運行時檢查。 但是 Rust 的內存規(guī)則并不比 Node.js 或 Python 更安全,用 Rust 編寫的 Web 應用程序在系統(tǒng)上不會比 Python 或 Ruby 應用程序安全。帶有垃圾收集器的高級編程語言通常為避免這類漏洞利用和錯誤而付出性能損失。不能在 JavaScript 中引用未初始化的內存,因為 JavaScript 中不進行內存間的引用。 旁注:這是在描述 Node.js 和其它系統(tǒng)的設計目標——它們確實偶爾會有 bug。Node.js 的緩存對象,就值得讀一讀。 你要是問一些人,他們會說如果使用不安全的代碼,Rust 相比帶有內存回收的編程語言是不安全的——包括最流行的 Web 框架 Actix(譯者注,Actix 是 Rust 的 Actor 異步并發(fā)框架,基于 Tokio 和 Future,開箱具有異步非阻塞事件驅動并發(fā)能力,其實現低層級 Actor 模型來提供無鎖并發(fā)模型,而且同時提供同步 Actor,具有快速、可靠,易可擴展 https:///),因為不安全代碼允許原始指針的延遲。 如果你正在寫一個視頻游戲,暫停執(zhí)行垃圾收集是不好的。如果你在編寫微控制器代碼,任何內存“開銷”或浪費都是非常糟糕的。但是大多數 Web 應用程序可以節(jié)省一點內存開銷來換取生產性能。 Rust 的其它屬性面對的爭議幾乎一樣。它的并發(fā)特性是太神奇了,如果你在做一些復雜的事情,需要快速響應,這當然很棒。但如果情況不是這樣呢?至少可以說,Rust 的異步生態(tài)系統(tǒng)面臨著很大挑戰(zhàn):各種不相關的領域中有著不同的異步實現,比如 tokio。 相比較之下,Python 的 Tornado 和 Twisted 異步實現的很奇怪,Node.js 異步實現的很好,但語法都很丑陋。 我確信,Rust 的異步將會穩(wěn)定和統(tǒng)一,未來會更容易操作,但我現在就要用啊。 很多人正在學 Rust,用 Rust 編寫 CLI 應用程序或底層代碼,并且玩得非常開心。使用 Rust 編寫普通 Web 應用程序的人明顯少很多。 這是技術選擇中的重要部分:是否有人在使用該工具?他們大致在同一個領域嗎?不幸的是,Rust 生態(tài)系統(tǒng)中許多令人難以置信的令人興奮的工作與 Web 應用服務器無關。的確存在一些很有前途的 Web 框架——甚至更高層次的框架,但毫無疑問,它們市場很小。即使是主要的 Web 框架 Actix 也只有幾個頂尖貢獻者。 如果 Rust 以目前的速度增長,那么社區(qū)中的 Web 部分將達到一個臨界值,但我認為沒有足夠多的人使用 Rust 作為網站的實用工具。與其它社區(qū)相比,有很多公司致力于使用現有的工具來構建 Web 應用程序,這些工具不是最前沿的,但足夠將成熟技術與新技術區(qū)分開來。 這一部分不僅僅是 Rust,它還涉及 GraphQL 生態(tài)系統(tǒng),Rust 參與這個生態(tài)系統(tǒng)就是一個例子。 N+1 問題是每個構建 Web 應用程序的人都應該知道的。要點是:你有一頁照片(一次查詢),你要顯示每張照片的作者,會有多少次查詢:1,合并照片和作者,或者在檢索照片后對每張照片進行查詢以獲取作者?或者兩次,第二次查詢 ids 中的 user.id,一次獲取所有作者,然后重新設置他們的照片屬性。 N+1 查詢通常優(yōu)先使用數據庫解決:比如將 N+1 查詢改為單個查詢,會帶來明顯的性能優(yōu)化。我們有很多方法來嘗試和解決這些問題:你可以編寫 SQL,并嘗試使用 CTE 和 JOIN 在單個查詢中完成大量工作,就像我們在 Observable 中所做的那樣,或者使用像 ActiveRecord 這樣的 ORM 層將 N+1 查詢轉換為可預測查詢的快速方法。 Juniper 是一個用于 Rust 應用程序的 GraphQL 服務。GraphQL 基本上都是由前端應用程序定義查詢,而不是后端。給它一系列可以查詢的東西,然后應用程序(React 或其它)將任意查詢發(fā)送到后端。 這會讓后端變得復雜。任何 SQL 級別的優(yōu)化都不可能做到——你的服務器正在編寫動態(tài) SQL,優(yōu)化只能依賴 GraphQL 服務,但它不會總是有效。例如:Juniper 默認情況下執(zhí)行的是 N+1 查詢,解決方案 dataloader 還比較粗糙且需要單獨維護。因此,最終您將擁有一個非??斓膽贸绦驅?,但它所有的時間都花在了極其低效的數據庫查詢上。 總之,GraphQL 與 NoSQL 數據庫配合使用效果非常好,它可以快速為這些類型的請求提供服務。我確信 Facebook 內部有一些特定的數據庫與 GraphQL 結合在一起使用效果非常棒,但業(yè)內其他企業(yè)則非常依賴 Postgres 和同類產品。 首先,本文提到的問題并不針對在通用場景使用 Rust,只針對將 Rust 用于特定目標和生態(tài)系統(tǒng),簡單說就是 Web API。 注意事項 1:一般情況下,你可以用任何編程語言搭建網站,還記得基于 C++ 實現的 OkCupid 嗎?(譯者注,OkCupid 是美國一個大型線上交友網站)還有一個非常流行的星象應用程序,Co-star,它全部是用 Haskell 編寫的。如果你擅長其它編程語言,或者可以招聘到擅長這些編程語言的工程師,你一樣可以取得成功。 注意事項 2:我試圖構建的是重 CRUD(增刪改查)的 Web 應用程序 API。它可能不算是一個 Web“服務”——主要是快速、無數次地執(zhí)行同一個操作,而是一個 Web“應用程序”——執(zhí)行了許多不同的操作,包含了相當多的業(yè)務邏輯。如果你要開發(fā)的東西跟我在做的不一樣,那我的建議可能就不適合你。如果你需要的是快速執(zhí)行一兩個操作,比如你正在寫一個支付網關或語音消息應用程序,那 Rust 可能效果還是不錯的。 注意事項 3:這篇文章寫于 2021 年 1 月,如果接下來社區(qū)繼續(xù)發(fā)展,Rust 將得到持續(xù)的改進,會變得更好并更易于 Web 應用程序開發(fā)。 總而言之,我真的很喜歡使用 Rust,這是一門美麗的編程語言,有很多很酷的想法。希望很快,Rust 會成為能用來構建我想做的東西的最合適的工具。不過,現在我想做的很多東西都要采用不同特性的編程語言才能更好地運行。 原文鏈接: https:///2021/01/15/rust.html |
|
來自: 西北望msm66g9f > 《編程》