整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          從 25 分鐘到 7 分鐘,我們用了這些方法提升 R

          從 25 分鐘到 7 分鐘,我們用了這些方法提升 Rails CI 的效率

          近,我們在 Gusto 創下了一個新紀錄:6 分 29 秒。

          這是我們為 Gusto 最大的一個應用程序,一個 Rails 單體程序運行測試套件所花費的時間。6 分 29 秒是公司的持續集成(CI)流水線啟用以來的最快紀錄。上一次 CI 套件跑出這樣的成績,公司的規模還很小,而現在我們共有全球數百名工程師在使用這個 Rails 單體應用,為全美 1% 的小型企業提供支持。

          對 Gusto 而言,高速 CI 流水線并不只是做做樣子,我們把它視為一種競爭優勢,代碼部署越快,那么客戶的業務開展也會越快。隨著 CI 速度的提升,工程師的生產率也在提高,CI 時間每縮短一分鐘,Gusto 每位工程師每周可增加 2%的拉取請求。

          我們的目標很簡單,希望讓測試套件的速度成為一個參數的函數,這個參數就是:我們愿意花多少錢?將基礎架構簡化到這個層面后,就更容易做成本效益分析,例如如果想要將構建速度從 7 分鐘提升到 5 分鐘,那么需要花費 1 美元。

          這篇文章介紹了我們是怎樣加快測試套件速度的,其中涉及一個 Rails 單體程序和一個主要用 React 編寫的 JavaScript 單頁應用程序(SPA),這些經驗適用于所有速度較慢的測試套件。

          我的同事 Kent 說,構建軟件有 3 個步驟:

          讓它跑起來(Make it work)

          讓它走上正軌(Make it right)

          讓它跑得更快(Make it fast)

          “讓它跑起來”指的是做出不會隨便崩潰的軟件。在這一步代碼可能晦澀難懂,但足以為客戶提供價值,并且通過了測試,讓我們能信任它。沒有測試,就很難判斷“它能行嗎?”

          “讓它走上正軌”指的是要讓代碼可維護,且易于更改。代碼不僅能在計算機上運行,更要讓人容易理解。新來的工程師可以輕松向代碼添加功能,代碼中的缺陷也應該很容易隔離和糾正。

          “讓它跑得更快”指的是要提升軟件性能。為什么它會是最后一步呢?對于像 Gusto 這樣的金融科技公司來說,如果只關注速度卻無視質量,那么我們的客戶和我們自己就離破產不遠了。并非每段代碼都需要優異的性能,如果一段代碼每天可能只執行一次,那么就算它有 " 高性能 " 水平,卻難以閱讀和理解,那也是一段失敗的代碼。

          我們把這套原則應用在 CI 套件的提速優化過程中。

          讓它跑起來

          消除不可靠測試

          首先需要做的事情是消除測試套件中的不可靠測試(test flakes)。不可靠測試(flaky test)指的是結果不確定的測試,它有時會通過,有時會失敗。速度飛快但不可靠的測試套件并不能讓你確信代碼可以正常運行,這只是在拋硬幣賭運氣而已。

          為了讓一個規模龐大的工程團隊消除不可靠測試,我們采用并執行了以下政策:

          在 master 分支上所有失敗的測試都將視為不可靠的。這些測試將標記為已跳過(skipped)。負責不可靠測試的團隊可以在空閑時修復它們并取消跳過標記。

          這個做法不僅能讓測試套件一直亮綠燈,同時也讓各個團隊決定何時編寫更多確定性測試。他們可以立刻開始編寫,也可以選擇等到再次處理這個功能時再行動。這種方法減少了一個團隊的不確定測試給其他團隊帶來的損害。

          當然,這種方法也存在質疑,“如果我們跳過了一項重要的測試該怎么辦?”是最常見的問題。沒錯,這個問題很重要,但我們需要搞清楚問題的背景。一個測試之所以會被標記為已跳過,是因為它會隨機失敗,首先要考慮的是我們對這個測試和功能到底有多大的信心。很多時候,測試會出現不可靠情況是因為生產環境中的確存在錯誤!

          通過這種方式,我們在主分支上的構建綠燈率從約 75%增至 98%!

          讓它走上正軌

          回到默認狀態

          隨著時間的流逝,我們逐漸偏離了運行 RSpec 測試的默認路徑。遵守默認值是很難的。下面是 RSpec 測試的一些默認值:

          • 在各個測試用例之間重置狀態。這樣可以確保測試是可重復的、確定性的,并且不會相互依賴。
          • 測試執行是隨機的。這樣可以確保測試之間不存在相互依賴,幫助避免測試污染。
          • 測試文件使用 Rails 自動加載器。這意味著我們僅加載應用程序所需的部分,而不是程序整體,可以幫助避免不完整的測試設置。

          重新采用這些默認值的過程并不輕松。確保每個測試用例都重置其狀態(數據庫、Redis 值、緩存等),都會帶來新的不可靠測試。根據其性質,我們可以修復更改或將之前正常的測試標記為不可靠。

          我們慢慢重新引入了 RSpec 默認值,這為測試提速奠定了基礎。

          讓它跑得更快

          引入測試時間上限

          我們的測試是不平衡的。有些測試文件只需幾毫秒就能執行完畢,還有些則需要花費數十分鐘時間。耗時幾分鐘的測試是集成測試,涉及我們應用程序中最重要的一些流程。我們希望這些測試的速度能更快,但并不想移除它們。

          因為測試套件是分布在多個節點上并行執行的,所以很快就遇到了測試提速的瓶頸。

          我們的測試套件速度取決于最慢的測試文件,因此實施了一項新政策:

          任何測試文件的執行時間都不能超過 2 分鐘。

          這個門檻是憑空拉出來的,但似乎很實用。我們只有 40 多個耗時超過 2 分鐘的文件。

          確定界限之后,我們開始處理速度緩慢的測試,試圖讓它們通過新的門檻,之前 40 個文件的時間都降到了閾值以下。之后,每個團隊都有責任確保其測試文件的執行時間不超過 2 分鐘,而執行時間超過 2 分鐘的測試文件會被標記為已跳過。

          根據最壞情況來平衡測試

          現在我們有了一個可靠的測試套件,只是速度很慢,它可以按任何順序執行測試,但是將測試分配給節點的方法是隨機的。有些節點只需幾秒鐘就完成了,而另一些節點則需要數十分鐘。我們怎樣才能讓它們平衡呢?

          我們面臨的最后一個問題是測試平衡。我們在這一步評估了兩種解決方案:

          1. 開發一個隊列,以在節點準備就緒后為其輸入測試用例。雖然這種方案原理上沒問題,但 RSpec 需要對框架做大幅更新才能兼容這種方案。此外,它在所有各不相同的并行作業之間引入了共享狀態。
          2. 在一次 CI 流程開始時在一個數據庫中記錄測試時間,將測試分為不同的桶,讓所有分組都有相同的長度。

          我們采用了記錄與分桶的方法將測試分配到各個節點上,因為它非常適合 knapsack 。測試運行期間,這種方法也不會在許多不同的并行作業之間共享狀態。這是很重要的,因為一個共享隊列可能有數百個節點,每個節點每秒為一個構建可以請求數千次工作。

          我們建立了一個 MySQL 實例來記錄所有文件的測試時間。在每次 CI 流程開始時,它會根據每個測試文件的第 99 個百分位時間生成一個 knapsack 文件。在每次 CI 流程結束時,它將上傳新的結果。

          為什么是第 99 個百分位?由于我們在共享硬件(AWS)上運行 CI,因此無法控制基礎架構,各個測試文件的測試時間會大相徑庭。我們無法將這些波動與使用的 EC2 實例類型,或者其他任何可以衡量的參數關聯起來。

          我們沒有進一步完善構建基礎架構,而是讓系統具備了彈性。我們使用第 99 個百分位來組織測試,從而保證了測試的性能表現有一個下限,而不是在獲得較好的平均性能時卻存在明顯偏低的個例。即便底層硬件發生變化或基礎架構層出現故障,CI 管道依舊能保障可預期的性能水平。

          這套策略實施之后,我們就有了一個自平衡的系統。測試越多,系統也就越平衡。如果某些測試隨著時間的推移變慢,則測試桶也會隨之調整平衡狀態。

          提升并行度

          現在到了有意思的地方:讓測試速度真的變快。

          這里的主要做法是增加并行度。項目開始以來,我們已經從 40 個并行作業增加到了 130 個。這稍稍增加了成本,但大幅提升了 CI 的運行速度。在 Gusto,我們使用 Buildkite 作為 CI 基礎架構,但這種并行化的理念適用于所有主流 CI 產品。

          雖然我們將并行度提高到了 3 倍以上,但 CI 費用卻沒有隨之線性增長。為什么?因為我們更好地利用了已有的 CPU 時間,通過在各個節點之間平衡作業,總 CPU 時間并沒有變化,但是實際運行時間大幅縮短了。

          總結

          在過去幾個月中,我們在一點點讓 Gusto 主要應用程序的 CI 管道變得更堅實可靠,而且速度更快。

          這種改進依舊是一項日常工作。在出現不可靠測試時我們還是會跳過它們,或者尋找新的優化策略來加快構建速度。無論你們現在使用的是什么技術,我們都希望這篇文章可以為你們的團隊提供一個路線圖參考,幫助改進你們的 CI 管道和軟件發布架構。

          關注我并轉發此篇文章,私信我“領取資料”,即可免費獲得InfoQ價值4999元迷你書!

          日分享最新,最流行的軟件開發知識與最新行業趨勢,希望大家能夠一鍵三連,多多支持,跪求關注,點贊,留言。

          如果您正在使用 Ruby on Rails 開發現代單頁應用程序,您很可能會使用一些花哨的 JS 框架來很好地更新您的 UI,而無需重新加載頁面。如果不使用它們,您將無能為力;這些天來這是一種標準......直到Rails得到了Hotwire。

          使用 Hotwire,您無需編寫大量 Javascript 即可獲得快速且響應迅速的 Web 應用程序。嗯,聽起來不錯,但 Hotwire 是什么?在本文中,我們將介紹 Hotwire 的基礎知識并使用它構建一個示例應用程序。

          響應式 Rails 應用程序有哪些選項?
          2013 年 6 月 25 日,Rails 4 發布,引入了 Turbolinks。Turbolinks 為 Rails 的“響應能力”做了什么?Turbolinks 攔截所有鏈接點擊,而不是發送常規GET請求,而是發送異步 Javascript 請求 (AJAX) 以獲取 HTML。然后它合并head獲取頁面的標簽并替換頁面的整個body標簽,因此不會重新加載整個頁面。無需重新加載樣式表或腳本,這意味著更快的頁面導航。但它仍然在替換整個body頁面,而不僅僅是更改頁面的某些部分。

          但是,如果您只想重新加載已更改的部分怎么辦?當您將某些元素標記為 時,您可以使用 Rails AJAX 助手data-remote='true',這使得這些元素發送 AJAXGET/POST請求而不是常規GET/POST請求。Rails 以生成的 JS 代碼進行響應,然后由瀏覽器執行以動態更新頁面的這些部分。

          然后我們可以在前端使用一些 JS 組件(例如,使用 React),以使應用程序感覺更加響應。所以,JS 組件發送一個 AJAX 請求,Rails 服務器用 JSON 數據響應它。然后前端框架將接收到的 JSON 轉換為 DOM 元素并更新 DOM 以反映這些變化。而且效果很好;唯一的缺點是它在頁面上混合了服務器端渲染和客戶端渲染。

          如今,另一種更傳統的方式是全力以赴并在前端使用 React、Vue 或其他 JS 框架來僅使用客戶端渲染,即所謂的單頁應用程序 (SPA)。使用這種方法,前端是一個單獨的應用程序,它將 AJAX 請求發送到 Rails 服務器,而 Rails 只是一個 JSON API。您可能知道,構建、維護和部署兩個具有可互換數據的獨立應用程序非常復雜。

          但是,如果您可以構建一個 SPA,而不需要構建兩個單獨的應用程序和編寫大量 Javascript 代碼的復雜性呢?以下是 Hotwire 可以為您提供的幫助。

          什么是Hotwire?
          Hotwire 是構建類似 SPA 的 Web 應用程序的另一種方法,它使用 Rails 模板呈現所有 HTML 服務器端,同時保持應用程序的快速響應。在服務器端保持渲染使您的開發體驗更簡單、更高效。Hotwire 名稱基本上是“HTML Over the Wire”的縮寫,意思是從服務器向客戶端發送生成的 HTML 而不是 JSON。它也不需要您編寫太多自定義 javascript 代碼。Hotwire 由 Turbo 和 Stimulus 組成。

          什么是Turbo gem?
          Turbo gem 是 Hotwire 的核心。它是一組動態更新頁面的技術,通過將頁面劃分為可以利用 WebSockets 作為傳輸進行部分更新的組件來加速導航和表單提交。如果您曾經在 Rails 中使用過 WebSockets,那么您很可能知道 Rails 使用 ActionCable 來處理 WebSockets 連接,并且它默認包含在 Rails 中。Turbo gem 由 Turbo Drive、Turbo Frames 和 Turbo Streams 組成。

          Turbo Drive
          Turbo Drive 用于攔截鏈接點擊(就像 Turbolinks 之前所做的那樣)并攔截表單提交。Turbo Drive 然后合并頁面的 head 標簽并替換頁面的 body 標簽。在與 Turbolinks 相同的情況下,不會重新加載整個頁面,這對于某些頁面可能會很快,但響應速度不如 2022 應用程序預期的那樣,因此您可能會考慮僅更新頁面的某些部分,而不是整個頁面. 這就是 Turboframes 派上用場的地方。

          Turbo Frame
          您可以通過簡單地將頁面的一部分包裝在turbo-frame具有唯一 id 的標簽中來簡單地使頁面的一部分成為 Turbo Frame。

          <turbo-frame id="13">


          在眾多WEB框架中,國外大型科技公司廣泛使用的兩個主要框架是 Ruby on Rails 和 Django。 Django 是一種 Python 編程語言框架,許多企業在其應用程序和網站項目開發中使用它,例如 Dropbox、YouTube、Instagram 和 Spotify等,Ruby on Rails,它是一種 Ruby 編程語言框架,已經在包括 Shopify、Bloomberg、Airbnb 和其他領先公司在內的研發產品中使用。本文將對 Django 與 Ruby on Rails 將進行對比。

          Django

          介紹

          Django是一個開放源代碼的Web應用框架,由Python寫成。采用了MVT的軟件設計模式,即模型Model,視圖View和模板Template。它最初是被開發來用于管理勞倫斯出版集團旗下的一些以新聞內容為主的網站的。并于2005年7月在BSD許可證下發布。這套框架是以比利時的吉普賽爵士吉他手Django Reinhardt來命名的。Django的主要目標是使得開發復雜的、數據庫驅動的網站變得簡單。Django注重組件的重用性和“可插拔性”,敏捷開發和DRY法則(Don't Repeat Yourself)。在Django中Python被普遍使用,甚至包括配置文件和數據模型。

          特點

          Django的優點

          • 功能完善、要素齊全:自帶大量常用工具和框架(比如分頁,auth,權限管理), 適合快速開發企業級網站。
          • 完善的文檔:經過十多年的發展和完善,Django有廣泛的實踐案例和完善的在線文檔。開發者遇到問題時可以搜索在線文檔尋求解決方案。
          • 強大的數據庫訪問組件:Django的Model層自帶數據庫ORM組件,使得開發者無須學習SQL語言即可對數據庫進行操作。
          • Django先進的App設計理念: App是可插拔的,是不可多得的思想。不需要了,可以直接刪除,對系統整體影響不大。
          • 自帶后臺管理系統admin:只需要通過簡單的幾行配置和代碼就可以實現一個完整的后臺數據管理控制平臺。
          • Django debug信息詳盡: 很容易找出代碼的錯誤所在。

          Django的缺點

          • 大包大攬: 對于一些輕量級應用不需要的功能模塊Django也包括了,不如Flask輕便。
          • 過度封裝: 很多類和方法都封裝了,直接使用比較簡單,但改動起來就比較困難。
          • 性能劣勢: 與C, C++性能上相比,Django性能偏低,當然這是python的鍋,其它python框架在流量上來后會有同樣問題。
          • 模板問題: django的模板實現了代碼和樣式完全分離,不允許模板里出現python代碼,靈活度對某些程序員來說可能不夠

          架構

          Django已經成為web開發者的首選框架,是一個遵循 MVC 設計模式的框架。MVC是Model、View、Controller三個單詞的簡寫,分別代表模型、視圖、控制器。Django其實也是一個MTV 的設計模式。MTV是Model、Template、View三個單詞的簡寫,分別代表模型、模版、視圖 。但是在Django中,控制器接受用戶輸入的部分由框架自行處理,所以 Django 里更關注的是模型(Model)、模板(Template)和視圖(Views),稱為 MTV模式。它們各自的職責如下:

          層次

          職責

          模型(Model),即數據存取層

          處理與數據相關的所有事務: 如何存取、如何驗證有效性、包含哪些行為以及數據之間的關系等。

          模板(Template),即表現層

          處理與表現相關的決定: 如何在頁面或其他類型文檔中進行顯示。

          視圖(View),即業務邏輯層

          存取模型及調取恰當模板的相關邏輯。模型與模板的橋梁。



          Rails

          介紹

          Ruby on Rails (RoR) 是一個用 Ruby 寫就的web開發框架,并且Ruby“famous”也經常被認為是歸功于它調了約定大于配置和測試這兩個方面。Rails 的約定大于配置(CoC)意味著幾乎沒有配置文件, 只有實現約定好的目錄結構和命名規則。它的每一處都藏著很多小魔法: 自動引入, 自動向視圖層傳遞控制器實體,一大堆諸如模板名稱這樣的東西都是框架能自動推斷出來的. 這也就意味著開發者只需要去指定應用程序中沒有約定的部分, 結果就是干凈簡短的代碼了

          特點

          RoR的優點

          • 易于處理小型項目
          • 有著豐富的第三方 gem(gem 是一個可以復用的打包好的 Ruby 應用程序或者類庫) 或插件,Ruby on Rails 具有基于 gems 和插件的組件結構,這使得有經驗的開發人員可以使用更少的代碼快速開發高效的應用程序。該框架提供了易于使用且文檔齊全的插件。不斷有新的 gem 被添加到存儲庫中,例如 RubyGems 資源有很多這樣的 gem
          • 社區龐大有大量的教程和指南

          RoR的缺點

          • 代碼可能難以閱讀,由于開發人員可以通過多種方式編寫相同的結果,這使得代碼難以閱讀
          • 難于創建API,由于其復雜性,使用 RoR 構建 API 也很困難


          架構

          Rails的 MVC 架構

          Ruby on Rails的模型-視圖-控制器架構由以下各部分組成:

          • 模型:模型包含著應用的狀態,狀態可能是臨時的也可能是長久性保存在數據庫中的。需要注意的是模型不僅包含數據,而且包含數據代表的邏輯。在 Rails 中,模型通常是由一些代表關系數據庫中RDBMS表的類組成的。在RoR中,模型類是通過Active Record模式進行處理的。一般來說,程序員要做的是繼承ActiveRecord 類,同時程序會自動計算出要使用哪個RDBMS表,這個表有哪些列。表與表之間的關系通過簡單的命令來指明。
          • 控制器:控制器將用戶界面和數據模型關聯起來,并充當協調運作的角色。它接收各種用戶操作,更新數據模型,并用合適的view展示結果給用戶。象他的名字一樣,可以說應用的主要控制中心就是各個控制器。
          • 視圖:View 負責根據 Model 中的數據顯示用戶界面。作為 web 應用,Rails 里的View通常是生成整個或者部分網頁。當然可以是XML或者甚至是JavaScript代碼。表現為使用內嵌Ruby的 HTML/XML/JavaScript 模板,

          Rails 的組成模塊

          • 模型:Active Record。ActiveRecord實現了Rails的對象關系映射。
          • 控制器:ActionPack 。ActionController 是Rails中的控制器,提供各種方法供用戶操作使用。
          • 視圖:ActionView 是Rails中的視圖,負責展現用戶界面。
          • 常用實用工具:ActiveSupport。ActiveSupport包提供一些工具和支持代碼。
          • 處理郵件:ActionMailer 。ActionMailer 用來發送和接收 email。  Web服務:ActionWebService


          總結

          RoR 和 Django 是很好的 Web 開發框架,框架之間的主要區別在于語言方法。它們都可以提供干凈、模塊化的代碼,并有助于減少在編碼上花費的時間。這些框架在建模域、應用程序數據的呈現、用戶交互等方面遵循相同的 MVC 原則。選擇 RoR 還是選擇 Django 取決于業務目標和對象。 Django 具有可擴展性且更易于理解。它有許多功能可以幫助簡化您的開發過程。


          主站蜘蛛池模板: 日韩精品无码免费一区二区三区| 精品国产一区二区三区| 国产在线精品观看一区| 岛国无码av不卡一区二区| 精品国产一区二区三区不卡| 中文字幕无码免费久久9一区9| 成人区人妻精品一区二区不卡| 一区二区三区精品| 国产在线精品一区二区中文 | 丝袜美腿高跟呻吟高潮一区| 99精品国产高清一区二区麻豆 | 在线播放国产一区二区三区| 国产精品一区二区av不卡| 国产一区韩国女主播| 国产品无码一区二区三区在线| 亚洲一区二区三区亚瑟| 日韩精品区一区二区三VR| 国产成人无码一区二区三区在线| 色系一区二区三区四区五区| 国产精品久久亚洲一区二区| 日本精品3d动漫一区二区| 激情内射亚洲一区二区三区| 无码人妻久久久一区二区三区| 日本不卡一区二区三区视频| 久久久精品人妻一区二区三区 | 精品一区精品二区| 精品一区二区三区水蜜桃| 麻豆视传媒一区二区三区| 日韩动漫av在线播放一区| 日本美女一区二区三区| 精品福利一区二区三区| 久草新视频一区二区三区| 一区二区三区四区精品视频| 日本一区午夜艳熟免费| 精品久久一区二区| 在线观看日本亚洲一区| 国产一区二区三区免费视频 | 一区国产传媒国产精品| 人妻互换精品一区二区| 日本美女一区二区三区| 日韩免费视频一区二区|