我們每天都要在instagram改進後台**30到50次,但工程師們只在極少數的情況下需要將這些修改上傳到主伺服器上進行部署,但大部分情況下**可以自我改進以達到預期的效果,無須人為干涉。這可能聽起來不可思議,但持續部署早已開始應用。
這篇文章將講述我們是如何實現持續部署,並讓它協調地執行。
為什麼這麼做?
對我們來說,持續部署有很多優勢:
應用
我們在結構上使用迭代的方法,很大程度上讓持續部署變為可能。我們不斷修改當前機制,直到它達到持續部署的要求。下面是在使用持續部署前的工作原理以及之後的測試執行機制。
在使用持續部署之前,工程師需要特別將整合好的開發部分進行部署。在他們進行修改除錯之後,必須親自部署,不然直到下乙個工程師這麼做之前,這些修改無法在虛擬環境下進行測試。在全域性測試之前,工程師希望能進行小規模的測試,所以他們先以一台機器進行部署,並進入那台機器檢查執行記錄,之後再進行所有終端的部署。所有部署由fabric script,乙個基本的資料庫和儲存大量部署記錄的叫」sauron」的使用者介面實現。
持續部署的第一步就是進行金絲雀部署,其實也就是寫指令碼。和之前不同,連續部署將指令碼應用到金絲雀機,跟蹤記錄部分客戶的使用情況,並不斷諮詢使用者們的滿意程度,以及決定是否進行全部部署。第二步就是對金絲雀機的一些基本分析:分析出乙份指令碼,收集並分類了每次請求後http狀態碼,而且還需要適用硬編碼率的閾值(比如,5xx的狀態碼小於0.5%,2xx的狀態碼不能小於90%)。然而,它只能警告使用者資料是否在閾值以內。
我們已經有乙個測試集,但只能在工程師的開發機器上執行。**審閱者無法確定修改的環節最終在虛擬環境下的測試結果,因此他們只能盲目的通過測試,等待在虛擬環境下出現問題。所以我們只能設定好jenkins,在主伺服器上測試各個commit,並將結果記錄到sauron上。sauron會記錄最近一次無誤的commit,所以在部署時會自動提示選擇剛剛測試好的那個commit,而不是上次進行部署的。
和我們相似,facebook用phabricator(進行**審閱,並結合了乙個叫」sandcastle」的持續整合系統。我們每次進行修改或更新時也使用sandcastle進行測試並產生結果。
為了達成自動化,我們必須先做好以下基礎工作。首先加一些部署的狀態(執行中,執行完成,錯誤和終止),並做好警告的指令碼,以防之前的部署不是執行完成狀態。我們還要在使用者介面新增終止按鈕,以便將狀態變成「終止」,並讓指令碼偶爾檢查狀態並進行反饋。我們同時也加入了對於全部commit的記錄;不像先前sauron只記錄最近一次無誤的commit,現在sauron需要記錄在主伺服器上每乙個環節,而且可以隨時檢視每乙個環節commit的測試狀態。
接下來就是自動進行剩下的需要工程師們進行的決定。第乙個決定是部署哪乙個commit。一開始的演算法一定是盡可能少地選擇通過測試的commit,最多不可超過三個。如果每乙個環節都無誤,那麼每次需要選擇乙個未經測試的新commit,最多兩個連續還沒有通過測試的環節。第二個決定是部署是否成功。如果超過1%主機未能成功部署視作部署失敗。
現在來看,正常情況下進行部署簡化成了一系列的「是」和「否」的選擇(是否接受commit的修改,是否進行金絲雀測試,是否繼續進行全部部署)。所以我們下一步要做的就是讓系統自己回答這些問題,讓jenkins自己執行部署的指令碼。一開始,用jenkins的工程師們需要坐在他們的電腦前進行選擇,現在他們根本不需要管理,直接讓計算機自己決定。出現的問題
現階段,持續部署也並不是那麼如意,還有很多問題有待我們解決。
工程師們經常進行修改,使測試終止,最終導致到下一步主伺服器上的環節測試失敗,讓這些環節不能進一步部署。值班工程師需要留意這類問題,恢復引起問題的commit,等待恢復中測試通過,然後手動部署整個由於該問題積壓的任務,才能繼續持續部署。因為每次部署都只能進行一小部分環節,確實讓持續部署的優勢不再這麼明顯。這個問題反倒讓測試環節變慢,而且不可靠。我們進行了各種優化,爭取讓12-15分鐘的測試縮短到5分鐘內,並修復下部測試結構不穩定的問題,讓測試結果更加可靠。
儘管有所改進,我們依舊有很多需要部署的修改。任務積壓大多是由於金絲雀測試失敗(正確結果和非預期結果),但偶爾還有其他錯誤。當問題解決之後,自動部署會將每個環節乙個個進行部署,因此,清理積壓的任務是緩慢的,而且會推遲新的commit的部署。所以,一旦值班工程師發現了這個問題,他們會介入並將所有積壓的任務一併進行部署,而失去了持續部署的優勢。
為了改進,當出現任務擠壓時,我們將環節按照邏輯分類,並按照分類,一次自動部署多個環節,縮短任務程序。演算法設定好每次部署的時間(30分鐘),並計算每乙個等待部署的環節所需要的時間是否能在剩下的部署時間內完成,在這段時間內能進行幾次部署(用硬編碼的值),和一次部署能進行幾個環節。計算出來最大值,但最大值不可超過三個。這樣做讓我們在有限時間內盡快多次進行部署,並在合理的時間內部署到每乙個commit。
乙個具體導致任務積壓的原因是,當我們的下部結構增大時,部署速度下降。現在ssh**固定了整個認證ssh連線的核心,fab master處理也固定了管理所有任務的核心;到達了這樣的境地,所以解決方案指向了facebook散布式的ssh系統。指導原則
那麼,如果你要做的東西與我們比較相似,你需要做什麼呢?為了讓我們的系統正常執行,下面是一些重要的原則,你也可以用到自己的系統裡。
1. 測試:
測試集必須迅速,必須合理覆蓋,但也不必須完美。這些測試需要經常進行:在編碼審閱時,在應用修改時(或者報告錯誤的環節),以及在應用後部署前。2. 金絲雀測試:
你需要自動化的金絲雀測試,防止錯誤的commit部署到所有終端上。談不上完美,就算一串簡單的資料和閾值就已經非常理想了。3. 正常情況下的自動化:
你考慮所有情況,只需要把已知,常見的情況計算好就行。如果發現有異常,立馬停止自動處理,進行人為干預吧。4. 讓使用者的體驗更舒適:
我認為這種自動化的瓶頸是它可能會讓使用者和工程師們感到無法控制。解決方法就是提供讓使用者可以隨時看見哪項任務已經做好,哪項正在處理,或者理想狀態下,將要處理哪項任務。當然,合理的停止機制也是必須的。5. 做好失誤部署的心裡準備:
失誤的修改不可避免,但沒關係,你只需要盡快找出錯誤,並再測試即可。以上是一些其他公司可以應用的建議。持續部署系統沒必要非得複雜,只要從以上原則出發,簡潔為重,步步精煉即可。
下一步這個系統目前來說執行正常,但未來的挑戰將不會間斷,下面是一些我們希望克服的問題:
instagram正在迅速發展,伴隨而來的是更多修改與更新。我們需要保證部署的速度不會降低,讓每次進行部署的commit量控制到最小。一種解決的可能性是應用傳送通道,並把部署分成多個階段。
隨著提交修改的速度的加快,測試失敗以及任務堆積會影響更多的開發者。我們想阻止不良commit上傳到主伺服器並進行部署,所以我們想讓金絲雀測試作為landcastle的一部分來進行應用。在測試通過後,landcastle會測試生產流量的改變,並依據金絲雀閾值來決定這個commit通過還是需要修改。
我們想進一步提高金絲雀測試的錯誤檢測能力,我們決定收集並檢查更多的資料,比如檢查每乙個函式響應**。我們同時也摒棄了先前靜態的閾值,而從對照組的計算機上收集實驗資料,並和金絲雀測試收到的資料加以對比。
如果能減小那些沒有被測試出來的不良commt對全域性的影響,那就再好不過了。我們可以不像原來那樣先對乙個機器測試,再應用全部;現在在單個測試和全體應用之間增加多個階段(分成好幾個集或者區域),再進行下一步之前檢查是否合格。譯者:terry guan
校對:wendy
本文由 雲棲社群 原創編譯
Coolblue的持續部署
coolblue 的技術開拓者paul de raaij提出,持續部署會得到更強的責任感和更好的部署質量。規範預防 庫混亂,自動化檢查很合適完成冗長而無聊的檢查,人工檢查很合適去檢查 的邏輯和用法實際上是否成立。de raaij 寫了一篇博文 我們軟體的持續部署 在文章中他解釋了coolblue是如...
持續整合 持續交付 持續部署
持續整合 持續整合強調開發人員提交了新 之後,立刻進行構建 單元 測試。根據測試結果,我們可以確定新 和原有 能否正確地整合在一起。持續交付 持續交付在持續整合的基礎上,將整合後的 部署到更貼近真實執行環境的 類生產環境 production like environments 中。比如,我們完成單...
持續整合 持續交付 持續部署
參考 1 continuous integration 持續整合 持續整合強調對於開發人員的每個提交,立刻進行構建 單元 測試。根據測試結果,我們可以確定新 和原有 能否正確地整合在一起。2 continuous delivery 持續交付 持續交付在持續整合的基礎上,將整合後的 部署到更貼近真實執...