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