MyHeritage是如何實現釋出到生產環境的
\\\本文要點
\\
- 持續部署對業務、質量、速度和滿意度有著重要的影響。\\t
- 任何巨大的更改都開始於增量小步驟。\\t
- 任何完全持續部署得以應用之前,都需要一些測量到位,其中最重要的就是測試。\\t
- 持續部署是一個革命性過程,從“足夠好的事情”開始,並一路改進。\\t
- 手工指令碼和任務是易於出錯的(浪費的)和消耗時間的,因此應瞄準於實現整個流水線的自動化。\
你可能會提出疑問:“這又是一篇持續部署的文章嗎?”如果要讓我回答“是”或“不是”。那麼我可以回答“是”,因為該文的確是介紹持續部署(CD,Continuous Deployment)的;我也可以回答“不是”,因為文中將介紹我們在MyHeritage所實現的一種獨特的CD過程,其中涵蓋了測試、所有開發人員工作於同一分支(即主線Trunk)上,並且聊天機器人也構成了部署流水線的一部分,還有更多的內容。
\\引言
\\多年前,MyHeritage的研發部門同時在多個分支上工作,其中部分是長期存活的分支。一旦某個特性接近於準備好的階段,程式碼就會歸併到主線上。但是這樣的歸併的確是一種夢魘般的經歷,其中存在很多些衝突,並且要找出存在的問題,需耗費大量珍貴的研發時間。
\\我們在歸併上所面對的麻煩遠非如此。由於我們每週都要做部署,其中一些部署需要歸併來自於不同分支的元件,這些元件在此之前從未一起工作過。它們被規劃在一個“超大”的程式碼發行版(具有多個軟體包)中釋出。這樣的服務包的釋出過程是一個非常繁瑣、易於出錯並且令人感到沮喪的過程。
\\在與此類部署方式多次較勁後,我決定應啟動向持續部署工作方式的轉移。
\\預備知識:測試等級、特性標識、統計資訊和日誌
\\對於一家服務於9千萬使用者、具有27億條DNA樹結構概要、77億條歷史記錄和TB級敏感DNA資料的企業,要使企業轉換到持續部署方式,必須要以增量小步伐完成。我們必須要確保工作方式的更改不會影響到站點的穩定性。
\\我們邁出的第一步是對新編寫的後端和前端程式碼都新增單元測試。。但是單獨這樣做是不夠的,因為依然無法覆蓋已有的數百萬行程式碼。我們決定要解決這些遺留程式碼,採取的方法是通過對重要元件編寫整合測試和端到端測試(使用Cucumber)實現更廣泛的覆蓋。這些測試並沒有單元測試那樣有效,也更為緩慢。但是這些測試對於使用較少的開發工作實現更好的覆蓋上具有很大的優勢。很快,我們就達到了對程式碼塊合理覆蓋的程度。
\\(點選放大影象)
\\\\圖1 應用CD中的一個關鍵因素,是在多層次上實現測試。
\\我們已經形成對部分程式碼外部行為的控制能力,這主要是通過特性標識將特性暴露給使用者實現的。該功能使用了基本的鍵儲存值(出於高效能的考慮,採用了由Memcache支援的MySQL資料庫),並可以控制出於測試目的以及真正對使用者的特性暴露。為追蹤更改的情況,對這些控制的全部更改都儲存在一個審計表中。我們已經啟動了金絲雀釋出(通過暴露新程式碼給少部分使用者而實現)、對生產環境的監控。在一切執行良好的情況下,我們會逐步增加特性暴露。
\\(點選放大影象)
\\\\圖2 特性標識系統和所觸發的電子郵件通知。
\\與此同時,我們確保每個特性隨監控生產環境中特性行為的統計資訊和感測器一併釋出(例如成功或失敗次數、響應時間等)。我們瞄準採用秒為單位的最小可能取樣時間,特別是可以監控生產環境中嚴重問題的關鍵感測器。聯合詳細的日誌資訊,我們能在生產環境中發生問題時進行快速的分析。
\\隨著統計資訊和日誌訊息數量的增加,我們採用了一些有助於我們瞭解生產環境狀態的工具,例如NewRelic和ELK Stack。我們也開發了一些內部工具,簡化了對日誌資訊和日誌層級更改的理解和追蹤(即如何從一個穩定狀態發展到有問題的狀態)。這些工具每日會對所有負責監控並修復自身責任範圍內問題的開發人員傳送兩次報告。我們還開發了一個類似的工具,對我們所有的統計資訊進行掃描,並報告其中所發現的任何異常。
\\(點選放大影象)
\\\\圖3 狀態及日誌自動掃描的電子郵件報告。
\\新手入門:實驗開展持續整合
\\一旦所有的部署到位,我們就準備好開始“實驗”。實驗通過一小組開發人員以持續部署的方式構建一個新特性,即頻繁的提交,不存在分支,並且由開發人員負責將程式碼釋出到生產環境。
\\從釋出至生產環境是一個手工過程,其中使用了釋出服務包中所使用的同一指令碼。這並非是一種更新生產環境的理想方式,但是我們的實驗確實非常成功,並且有更多的敏捷團隊逐漸地轉換到這種工作方式。很快大家就拋棄了“打包服務”的方式。
\\我們已經認識到以持續部署方式工作的好處:
\\- 高速:不再需要在歸併上耗費時間。\\t
- 高質量:釋出到生產環境的程式碼片段更小,其中具有更少的軟體缺陷,並在發生失敗時易於追蹤(恢復更快)。\\t
- 更好的編碼:開發人員開始設計更為模組化的程式碼,這樣的程式碼可以分別獨自發布。同時提供了更好的可測試性。\\t
- 更高的滿意度:研發部門喜歡這樣的工作方式,我們的使用者也喜歡更為頻繁的更新。\
一路改進:流水線的自動化
\\不斷尋求提高的方法,是我們研發的價值觀之一。很顯然,下一步就是要改進手工釋出程式碼到生產環境這一過程。
\\為此我們建立了一個敏捷團隊,團隊目標就是自動化CD流水線。我們想要避免耗費時間去手工執行指令碼,這樣的指令碼必須由開發人員在特定時間手工呼叫。這種解決方案無法擴充套件,並且很浪費時間。
\\在完成一次Sprint之後,我們處於一種更好的狀態。我們所具有的解決方案使得開發人員可以從IDE提交程式碼並觸發構建,最終形成可供九千萬使用者使用的軟體釋出。
\\我們在後臺開發了一個Jenkins工作流。該工作流在對主線的任何提交(即我們的單一分支)之後呼叫。作為工作流的組成部分,我們執行如下的步驟(其中一些是並行開展的):
\\- 解析提交的訊息(結構化的):在啟動構建後,更新相關的人員。\\t
- 單元測試和整合測試。\\t
- 在JS極簡化後,構建包括主線快照的RPM。\\t
- 對於不從外部世界獲取流量的生產伺服器,將RPM上傳到一個金絲雀伺服器。\\t
- 在該金絲雀伺服器上執行端到端的測試(用於主使用者流程)。\\t
- 如果一切進展正常,將RPM上傳到一個程式碼庫伺服器,允許在每個生產機器上安裝的MCollective代理獲取並安裝新的RPM。\\t
- 在過程的最後,以通知電子郵件的形式傳送生產環境的更新情況。\
(點選放大影象)
\\\\圖4 由許多易於監控的步驟所組成的CD流程圖。
\\大家對這一“提交等同於部署”新過程的滿意度非常高。它使得開發人員能在一個完全自動化的過程中,在25分鐘內就將自身的程式碼從提交推送到生產環境。
\\更進一步的改進
\\我們在此期間學到了很多,並就如何進一步的改進收集了大量的反饋意見。其中包括:
\\- 與Slack對話機器人的整合:以指定會話通道報告構建進度,通知相關人員構建的進度。\\t
- 在任何生產環境更新後,啟用自動“日誌掃描”任務。如果日誌中存在大量的錯誤訊息,就在會話通道中進行報告。\\t
- 改進發布時間:在部署RPM到我們的大型伺服器農場的過程中,我們遇上了速度慢的問題。因此我們新增了一個HTTP反向代理,實現了RPM的併發上傳。\\t
- 為增加並行度,我們將測試分為多個組,進一步縮短了釋出時間。\\t
- 我們通過從程式碼庫移除資產,並藉助於一個專用於此的Jenkins流程,減少了RPM的大小。\\t
- 我們在Jenkins中新增了一個特殊的“回滾”任務,允許對生產環境做更快的恢復或是緊急更新。\\t
- 對於構建資訊以及特性標識的修改情況,我們對它們做索引並整合到ElasticSearch中,用於Grafana/Graphite的標註。這使得它們與其它度量一併可見,易於實現關聯分析。\\t
- 所有相關的更新以每日摘要電子郵件形式傳送,使得公司中的所有利益相關者同步掌握最新的更新情況。\
(點選放大影象)
\\\\圖5 在CD Slack通道中提供的典型CD進展情況報告。
\\(點選放大影象)
\\\\圖6 在構建失敗時給出的詳細資訊。
\\結論
\\持續部署是改進我們的質量、速度和滿意度的一個關鍵因素。企業在轉換到持續部署方式工作前,需要實現一些里程碑工作。一旦企業已經著手做更改,這將使企業的研發部門乃至整個企業受益匪淺。
\\謹以本文獻給那些我們研發部門中那些以持續整合方式工作的先行者,以及整個研發和DevOps部門。
\\本文作者簡介
\\Ran Levy是MyHeritage的研發副總裁,近六年來一直工作於MyHeritage。他具有20年的業界工作經驗,曾在複雜大規模系統中歷任開發人員、架構師和管理人員。Ran對敏捷和高效過程情有獨鍾,一直領導著公司向持續部署轉換的過程。
\\\\相關文章
- kafka生產環境規劃-kafka 商業環境實戰Kafka
- redmine生產環境搭建
- Django生產環境搭建Django
- 操作生產環境的規範
- 生產環境的 ElasticSearch 安裝指南Elasticsearch
- Vue生產環境除錯的方法Vue除錯
- 建立映象釋出到映象倉庫【不依賴docker環境】Docker
- webpack4生產環境和開發環境的對比Web開發環境
- 釋出ASP.NET Core程式到Linux生產環境ASP.NETLinux
- Webpack(開發、生產環境配置)Web
- Yarn生產環境核心引數Yarn
- 實戰生產環境vCenter HA配置(VCSA6.5)
- goldengate 生產環境下實施注意事項Go
- 黑馬部落格——詳細步驟(十)專案功能的實現之開發環境與生產環境開發環境
- 生產環境搭建MySQL複製的教程MySql
- 用 Spring 區分開發環境、測試環境、生產環境Spring開發環境
- Dubbo Mesh 在閒魚生產環境中的落地實踐
- SQLServer高可用方案在企業生產環境的實踐SQLServer
- 生產環境中如何切換MySQL儲存引擎GAMySql儲存引擎
- Webpack多頁面實現公共頭部尾部和分離生產環境Web
- 優思學院|什麼是精益生產?企業如何實現精益生產?
- Nacos 釋出 1.0.0 GA 版本,可大規模投入到生產環境
- OB有問必答 | OceanBase的記憶體管理是怎麼做的?在實際的生產環境中是如何應用的?記憶體
- Arthas 實踐——生產環境排查 CPU 飈高問題
- 開發環境是如何或一般每隔多久與生產庫同步一次的?開發環境
- docker 生產環境基礎應用Docker
- 生產環境nginx平滑升級演示Nginx
- laravel生產環境下新增欄位Laravel
- Eureka:生產環境優化總結。優化
- Yarn 生產環境多佇列配置Yarn佇列
- 生產環境中MySQL複製的搭建KPMySql
- 在Grammarly的生產環境中執行LispLisp
- ionic app 開發和生產環境的配置APP
- 三個生產環境中使用Docker的案例Docker
- 生產環境的redis高可用叢集搭建Redis
- Nuxt.js中配置生產環境和開發環境APIUXJS開發環境API
- Filebeat 收集K8S 日誌,生產環境實踐K8S
- PayPal將CRDT資料型別落實到生產環境資料型別