Lyft如何通過DevOps提升擴充套件微服務的生產力? - Garrett

banq發表於2021-11-22

該案例研究是關於在完成向微服務的整體遷移以及開發工具中出現的下一個約束之後提高 Lyft 的生產力。

2018 年底,Lyft 工程完成了將我們最初的 PHP 單體分解為 Python 和 Go 微服務的集合。幾年後,微服務在允許團隊獨立運營和交付服務方面取得了很大的成功。

本文由四部分組成的系列將介紹為 Lyft 工程團隊提供服務的開發環境,因為它從 100 名工程師和少數服務發展到 1000 多名工程師和數百個服務。我們將討論導致我們遠離大多數這些環境的擴充套件挑戰,以及主要基於大量整合測試(通常接近端到端)的測試方法,支援以本地為中心的方法單獨測試元件。

  • 第一部分:開發和測試環境的歷史(這篇文章)
  • 第二部分:優化本地快速開發
  • 第三部分:使用覆蓋在登臺中擴充套件服務網格
  • 第四部分:使用自動化驗收測試控制部署

 

開發和測試環境的歷史

我們對綜合開發環境的第一次重大投資始於 2015 年,當時我們達到了 100 名工程師。幾乎所有的開發仍然發生在 PHP 單體上,一些微服務開始出現用於不同的用例,例如驅動程式載入。

預計我們需要服務的工程師和服務數量會增加,因此遷移到容器很有意義。我們的計劃是構建一個基於 Docker 的容器編排環境——當時仍處於起步階段——首先為開發人員提供測試服務,然後擴充套件到生產,在那裡我們可以從更便宜、擴充套件速度更快的多租戶工作負載中受益。

  • 使用 Devbox 進行本地開發

Devbox——Lyft 的盒裝開發環境——於 2016 年初發貨,並很快被大多數工程師採用。Devbox 的工作方式是代表使用者管理本地虛擬機器——無需他們安裝或更新軟體包、配置runit以啟動服務、新增共享資料夾等。虛擬機器執行後,只需一個命令和幾分鐘即可拉取最新版本的映像、建立/種子資料庫、啟動特使代理sidecar 以及開始傳送請求所需的一切。

這是之前的一次精彩升級,我們為每個開發人員和服務組合手動配置 EC2 例項,這使得設定和保持最新變得乏味。我們第一次有了一種一致、可重複且簡單的方法來跨多個服務進行開發。

  • 使用 Onebox 進行遠端開發

對可以與其他工程師或功能(如設計)共享的更長壽命環境的需求很快變得明顯,於是 Onebox 誕生了。Onebox 本質上是 EC2 例項上的 Devbox,具有許多使使用者遠離 Devbox 的好處。我們將這些託管在具有 16 個 vCPU 和 122GiB 記憶體的 r3.4xlarge 例項上,這些例項比工程師隨身攜帶的 MacBook Pro 強大得多。Onebox 可以執行更多服務並更快地下載容器映象(因為在 AWS 中),更不用說避免 VirtualBox 導致膝上型電腦愛好者模仿噴氣發動機。

  • 整合測試

除了單元測試之外,Onebox 的雲基礎架構也非常適合在 CI 上執行整合測試。一個服務將簡單地在一個manifest.yaml檔案中定義它需要的一組依賴項,一個臨時的 Onebox 將啟動這些服務並對每個拉取請求執行測試。許多服務,尤其是靠近移動客戶端的組合服務,構建了大型整合測試套件以應對中斷。事後分析通常以新增新整合測試的操作項結束。有了如此靈活而強大的測試能力,單元測試逐漸退居次席。

  • 暫存環境

Lyft 的臨時環境幾乎與生產環境相同——除了更小的佔用空間和沒有生產資料——並且所有服務都在生產的途中部署在那裡。儘管不是開發人員環境,但由於它在端到端測試中發揮的作用越來越重要,因此 staging 值得討論。

在 Devbox 和 Onebox 於 2017 年初發布後不久,我們也在解決一種不同的增長問題:負載測試。導致拼車流量激增的事件(例如新年前夜和萬聖節)會暴露我們系統中的瓶頸,這通常會導致中斷。為了解決這些問題,我們構建了一個用於大規模模擬遊樂設施的框架。該框架針對我們的生產環境,協調了數以萬計具有不同配置的模擬使用者(例如,經常取消的洛杉磯司機)並將 Lyft 視為黑匣子。

作為在登臺中測試模擬框架本身的副產品,我們意識到生成的流量對於一般的端到端測試也很有價值。在登臺中不斷使用公共端點為部署提供了很好的訊號。例如,如果部署破壞了讓乘客下車的端點,部署的作者幾乎會立即看到錯誤日誌和警報。模擬還不斷為使用者、乘車、支付等生成最新資料,從而減少了開發過程中所需的大量手動測試設定時間。隨著負載測試工作使暫存變得比以往任何時候都更加現實和有用,團隊將 PR 分支部署在那裡作為獲得真實資料反饋的一致地方變得很普遍。

 

需要突破的約束問題

快進到 2020 年——在引入 Devbox 和 Onebox 作為容器化開發環境四年之後——儘管我們盡了最大努力,“Lyft-in-a-box”風格的環境仍在努力跟上。使用這些環境的工程師增加了十倍,現在有數百個微服務支援更復雜的業務。雖然在依賴較小的服務上開發仍然相當有效,但大多數開發發生在已經建立了巨大依賴樹的服務上——這使得在 CI 上啟動環境或執行測試變得非常緩慢。

雖然這些環境和測試能力是強大和方便,他們到達造成弊大於利的一個點。我們構建了一個為測試少數服務而優化的系統,並且沒有重新評估我們的策略,因為服務的數量——由我們的 PHP 單體的分解加速了——從 5 增長到 50、50 到 100,甚至更多。為開發啟動大量服務不僅需要大量的努力來維護和擴充套件,而且還迫使開發人員不斷地考慮整個系統而不是一次一個元件,從而削弱了整個開發人員的生產力.

。。。。

 

改變路線

大約一年前開始將我們的開發環境遷移到 Kubernetes 後,工程資源的變化是我們縮小規模並重新審視更大方向的催化劑。維護基礎設施以支援這些按需環境已經變得過於昂貴,而且只會隨著時間的推移而惡化。解決我們的情況需要對我們開發和測試微服務的方式進行更根本的改變。是時候用對由數百個微服務組成的系統來說可持續的替代方案來取代 CI 上的 Devbox、Onebox 和整合測試了。

仔細觀察開發人員如何使用現有環境,我們確定了三個對維護至關重要且需要投資的關鍵工作流程:

  1. 本地開發:對於任何給定的服務,執行單元測試或啟動 Web 伺服器併傳送請求應該是簡單且超快的。
  2. 手動端到端測試:測試給定更改在更大系統中的執行情況是許多工程師依賴的關鍵工作流程。我們希望擴充套件暫存功能,使開發人員能夠更輕鬆、更安全地以隔離方式進行測試。
  3. 自動化的端到端測試:儘管過度依賴這種測試,但如果沒有自動化 E2E 測試提供的信心,我們就無法繼續每天傳送數百次更改。我們將保留一小部分有價值的測試作為驗收測試——在部署到生產期間執行的測試。

本系列的以下帖子將深入探討這三個領域中的每一個,以討論問題領域、我們如何解決這些問題以及我們學到了什麼。請留意關於本地開發的下一篇文章,其中將分享更多關於我們在本地開發時用於檢查、模擬和改變網路請求的工具的資訊。

相關文章