1Password工程副總裁:Rust用起來真香

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"本文最初發佈於serokell.io網站,經網站授權由InfoQ中文站翻譯並分享。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Rust已經席捲了編程語言世界。自2015年發佈1.0版以來,它一直是最受歡迎的編程語言之一,且贏得了衆多忠實的開發人員和貢獻者。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"爲什麼那麼多開發者喜歡Rust?本文試圖回答這個問題。我們採訪了1Password工程副總裁Michael Fey。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/5d\/5d4c899825183f185a88d76e16583e7f.jpeg","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"問題1:能否介紹一下你所在的公司和擔任的角色?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"答:1Password是一個密碼管理器,獲得數百萬用戶和70000家企業的信任,被用來保護他們的敏感數據。它會記住你所有的密碼,這樣你就不用費勁記下它們了。它提供了適用於所有主要瀏覽器、桌面和移動設備的應用。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我是1Password客戶端應用工程副總裁。如果你在Mac、Windows PC、iPhone、iPad、Android手機或平板電腦,或在瀏覽器中使用1Password,那麼你使用的就是我們團隊開發的產品。我們的故事從2004年一直延續至今,我們爲構建精心設計的體驗並確保人們的線上安全性而感到自豪。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"問題2:能談談1Password的技術棧嗎?你們代碼庫有多少是用Rust編寫的?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"答:過去幾年,我們一直在1Password的生產環境中使用Rust。我們的Windows團隊是這項工作的先行者,現在的Windows版1Password 7大約70%的代碼是用Rust編寫的。我們還在2019年底將1Password Brain(驅動我們瀏覽器填充邏輯的引擎)從Go移植到Rust,這樣我們就能在我們的瀏覽器擴展中利用將Rust部署到WebAssembly的速度和性能優勢。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這些代碼已經投入生產環境有幾年時間,我們取得巨大成功。工作非常順利,所以我們現在幾乎完全重寫了整個產品陣容,而Rust是這個故事中的關鍵部分。我們正使用Rust創建一個無頭的1Password應用,其中包含所有業務邏輯、加密、數據庫訪問、服務器通信,以及包裝在我們的目標部署系統的一個原生UI層中的更多內容。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"問題3:將Rust用於1Password的決策是否考慮到Rust的優勢?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"答:最初吸引我們進入Rust世界的主要因素之一是內存安全性;得知Rust可以幫助我們儘可能提高對客戶敏感信息安全性的信心後,我們當然感到非常興奮。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"除了內存安全性外,Rust生態系統還有很多打動我們的優點。因爲Rust沒有傳統的運行時,因此性能有了顯著提升。例如,我們不必擔心垃圾收集器的開銷。Rust提供了一種“程序正確性”的形式,並提供了許多在運行時避免未定義行爲的保證。它的強類型系統在編譯時強制執行這些規則。只要精心在應用程序邏輯中融合Rust的強類型規則,API就很難被誤用,代碼也能得到簡化,因爲代碼無需在運行時檢查約束和不變項;Rust的編譯器可以在程序執行前確保其沒有無效的運行時代碼路徑,讓你的程序不會誤入歧途。需要做的運行時狀態驗證變少了,於是我們就可以生成更簡潔、更高效、更專注和更高質量的代碼。與其他語言相比,Rust需要的運行時調試很少。如果代碼可以編譯,開發人員就可以肯定它不會表現出意外的行爲。它可能不是你想要的,但會是“正確的”。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Rust另一個非常強大(卻經常被忽略)的特性是它的宏流程系統,它讓我們能夠編寫一種工具,可以自動與客戶端語言(Swift、Kotlin和TypeScript)共享Rust中定義的類型。該工具的輸出會自動處理序列化\/反序列化過程,這意味着我們的客戶端開發人員在與Rust庫交互時可以繼續使用他們選擇的語言工作,並且避免了通過外部函數接口(FFI)解析JSON的麻煩。我們獲得了所有這些優勢,同時享受了在我們每一種目標語言中做編譯時類型檢查的好處。我們也已將這款工具集成到我們的持續集成服務器中,這意味着對Rust模型的更改可能會導致客戶端應用程序的編譯失敗,而這種失敗會在我們的審覈流程中被捕獲。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"該工具已成爲我們開發流程中不可或缺的組成部分,讓我們獲得前所未有的前進速度。一旦我們在Rust中定義了類型,就可以立即用客戶端語言生成等效的類型。這讓我們的開發人員可以專注於解決問題,而無需手動編寫樣板代碼以通過FFI通信。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"問題4:在開發1Password這樣以安全爲中心的應用程序時,Rust提供的支持(庫和其他方面)有多好?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"答:Rust生態有足夠的能力來建立以安全爲中心的應用程序所需的大部分基礎。有兩個大型的頂尖加密平臺("},{"type":"link","attrs":{"href":"https:\/\/github.com\/briansmith\/ring?fileGuid=RwXKW63W3XhC3WcC","title":"","type":null},"content":[{"type":"text","text":"ring"}]},{"type":"text","text":"和"},{"type":"link","attrs":{"href":"https:\/\/github.com\/RustCrypto?fileGuid=RwXKW63W3XhC3WcC","title":"","type":null},"content":[{"type":"text","text":"Rust Crypto"}]},{"type":"text","text":"group),它們共同提供了豐富的功能選項。正如我上面提到的,使用Rust編寫代碼本身就可以讓你對內存使用有更多信心,並且減少了嚮應用程序中意外引入與內存相關漏洞的機率。還有一個完善的系統可以跟蹤不時出現在Rust板條箱中的漏洞:"},{"type":"link","attrs":{"href":"https:\/\/rustsec.org\/?fileGuid=RwXKW63W3XhC3WcC","title":"","type":null},"content":[{"type":"text","text":"RustSec"}]},{"type":"text","text":"數據庫,該數據庫由其他Rust開發人員在社區提供,並經常更新一些可在CI審覈掃描中使用的新信息。Rust和Cargo還帶有功能豐富的測試框架,爲開發人員提供了一種簡便的方法來編寫單元測試套件,以確保關鍵代碼(例如你編寫的各種加密函數)的行爲正確。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"儘管支持所有功能的安全的原生Rust庫還是一個夢想(它們遲早會成爲現實),但總有一種選項可以輕鬆地使用C或原生平臺庫中的某些東西。我們將其用於Rust代碼中,以高效實現諸如調用生物識別解鎖的原生實現(Touch ID、Face ID、Windows Hello)以及平臺特定的設置實現(例如蘋果平臺上的NSUserDefaults)之類的功能。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"問題5:有哪些Rust庫是你特別推薦的?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"答:Tokio、Hyper\/Reqwest、Ring和Neon都在1Password中擁有一席之地,它們對於這個雄心勃勃的項目而言至關重要。你還應該在crates.io上查看我們的"},{"type":"link","attrs":{"href":"https:\/\/crates.io\/crates\/password-rules-parser?fileGuid=RwXKW63W3XhC3WcC","title":"","type":null},"content":[{"type":"text","text":"password-rules-parser"}]},{"type":"text","text":",它基於一套主要由蘋果支持的規範。它們的工具和文檔可以在"},{"type":"link","attrs":{"href":"https:\/\/developer.apple.com\/password-rules\/?fileGuid=RwXKW63W3XhC3WcC","title":"","type":null},"content":[{"type":"text","text":"這裏"}]},{"type":"text","text":"找到。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"問題6:Rust用起來有哪些明顯的優勢,在你們的技術棧中有哪些不足?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"答:當我們開始這個項目時,Rust已經實現了我們期望的90%。我們已經能以某種形式將其部署到幾乎每個目標平臺上(Apple Watch除外)。這種語言本身的設計頗具現代感,並且每次更新發布時都在不斷改進。它有着出色的文檔資料和活躍的社區。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"儘管有無數可用的板條箱,但我們確實需要推出自己的日誌記錄和跟蹤工具,以確保它們在1Password中可以安全使用。此外,我們構建了一個實質上本地化的實現,以滿足我們產品的需求。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"它確實在一個關鍵方面無法滿足我們的要求:我們希望WebAssembly在瀏覽器和瀏覽器擴展方面能提供比現在更強大的能力。WebAssembly作爲一個函數庫來說非常出色,但嘗試在WASM中支持整個運行時一直是一個挑戰。但我們遇到的許多問題並不是Rust本身的侷限,而是WebAssembly作爲部署平臺存在的侷限。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"問題7:用Rust開發1Password時遇到的最大挑戰是什麼?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"答:我們團隊中的許多人都是Rust新手,他們經歷了內存管理和所有權模型的典型學習曲線。我們還發現編譯時間比較漫長,我們的CPU和風扇經受了不小的考驗。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"問題8:你們對結果感到滿意嗎?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"答:毫無疑問是滿意的。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"問題9:有哪些重要的收穫?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"答:如果你不熟悉Rust,請從小處入手,並以此爲基礎逐漸推進。當我們開始嘗試探索基於Rust的解決方案所能提供的優勢時,我們做了大量實驗。當你的實驗順利進行時,請嘗試重新思考一下你以前使用其他語言時的工作方式,看一看你的代碼是否可以從Rust的理念中受益。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"原文鏈接:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"https:\/\/serokell.io\/blog\/rust-in-production-1password?fileGuid=RwXKW63W3XhC3WcC"}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章