# Continuous Delivery 107-124 --- ## 第五章 部屬流水線解析 --- ### 引言 --- ### 什麼是部屬流水線? --- ### 抽象層面上 指軟體從版本控制 到使用者手中期間的 **自動化表現形式** --- >具體呈現出查看與控制每個變更的整個歷程 >包括每次變更被**提交**到版本控制開始 >直到通過各種**測試**和**佈署** >最後**發布**給使用者 > 容器化之後 會把部屬跟發布做結合 --- ### 實際上 將客戶或使用者腦中的一個想法 變成其手中真實可用的特性 ![](https://i.imgur.com/MMTiyLg.jpg) 本書僅討論右邊三個 --- ![](https://i.imgur.com/fzZQPRF.jpg "" =800x480) > 起點是每次對版本控制的提交 --- ![](https://i.imgur.com/ogLR54z.jpg) --- 有效阻止**未經充分測試** ![](https://i.imgur.com/AbQP3GN.jpg) 或**未滿預期的版本**進入生產環境 也能避免回歸缺陷 --- 當部屬和發布都被自動化之後 這些活動就變成快速、可重複且可靠 --- 發布工作變得容易 變成一件"平常"的事務 只要願意 就能頻繁發布 --- 如果支援了自動化的安全還原 發布風險就能大幅降低 最糟的狀況就是還原 --- 過程可分成下面四個階段 --- ### 提交階段 從技術角度斷言整個系統是可以運作的 此階段會進行編譯,執行自動化測試 > 主要是單元測試 程式碼分析 --- ### 自動化驗收測試階段 從功能性與非功能性的角度 斷言整個系統是可以運作的 針對系統行為,能滿足使用者的需要 並可符合客戶的需求規格 --- ### 手動測試階段 斷言系統的可用性 滿足系統要求 試圖發現自動化測試未能捕獲的缺陷 驗證系統是否已為使用者提供價值 通常包括 * 探索性測試 * 整合環境測試 * 使用者驗收測試 --- ### 發布階段 將軟體交付給使用者 可能是**套裝軟體** 也可能是佈署到**生產環境** 或**試運行環境** --- 佈署流水線就是由上述階段 以及為軟體交付流程建模所需的其他階段共同組成 有時也可稱為持續整合流水線、建置流水線、佈署生產線或現行建置 --- 根本上而言 就是個自動化的軟體交付流程 不是指不需要人的參與 指在執行階段,易出錯且複雜的步驟 會轉變成**可靠**且**可重複**的自動化流程 --- ## 最基本的佈署流水線 ![](https://i.imgur.com/m7KmjZ3.jpg) --- ### 第一階段 * 編譯程式碼 * 單元測試 * 程式碼分析 * 建立產出物 流程順利的話 會產生軟體binary,composer vendor,node_modules之類的流程產出物 利用Nexus,Artifactory之類的工具管理產出物 --- ### 第二階段 執行時間較長的自動化驗收測試 最好能支援將測試分成多組 以便能併行 提高執行效率 使能**更快獲取回饋** 應該是第一階段成功完成後能自動觸發 --- 可能會有分支出現 可獨立佈署到多個不同的環境 例如 * 使用者驗收測試環境 * 容量測試環境 * 生產環境 --- **不需要完全自動** 讓測試人員或業務人員可以手動選擇佈署腳本來執行 人員應可以看到版本做過哪些修改 以及簽入的註釋 之後只需點擊按鈕 即可觸發相應的佈署腳本 --- 不同階段的使用者各自傭有其環境使用許可 特定人士才有權限可以佈署 --- 所做的一切都是為了能盡快得到回饋 為了加速回饋 應讓每個部屬版本在流水線的哪個階段都要顯而易見 以方便追蹤是哪個版本在哪個階段出問題 --- ## 佈署流水線的相關測試 推薦實踐 --- ### 只產生一次binary(產出物) 如果每次都重新產生 可能版本之間使用的產出物會不一樣 導致問題難以追蹤 或者導致使用到本來不打算使用的版本 --- 重複編譯違反兩個重要原則 1. 保證佈署流水線導致的效率提升,使團隊提早得到回饋 2. 始終在**已知可靠**的基礎上進行建置 --- 此原則的必然成果之一是 能夠在任意環境上佈署產出物 促使將程式碼(對不同的環境是相同的)與設置(因環境而不同)分開放置 --- ### 為什麼產出物不應該與環境有相關性 不利於佈署的靈活性、方便性、和系統的可維護性 但有些工具會鼓勵這麼做 --- ### 對不同環境採用相同的佈署方式 * 使用屬性檔保存設置資訊 * 放到目錄服務中 * 放在資料庫 * 設定管理服務 --- 完全可以從**同一個來源** 找到在**所有環境**中執行之**所有應用程式**設置資訊 --- 使用相同的腳本對開發環境和生產環境佈署 此為避免"他在我的機器上可以運作"症狀的法寶 --- 如果使用同一個腳本在全部的環境下進行佈署 那當某個環境上的佈署失效時 就可以確定其原因一定來自於下面三方面 * 與該環境相關的設定檔,某項設置有問題 * 基礎設施或應用程式所依存的某個服務有問題 * 環境本身的設置有問題 要找出原因可以用下面兩個實踐解決問題 --- ### 對佈署進行冒煙測試 啟動應用程式,檢查是否能看到主頁面,並且看到正確的內容即可 應檢查依存的服務是否都已經啟動,且能正常執行了,例如資料庫 MQ 或外部服務 --- ### 在生產環境的副本中佈署 盡量在與生產環境相似的環境中進行測試和持續測試 確保 * 基礎設施是相同的,例如:網路拓撲結構和防火牆 * 作業系統(包含修補程式的版本)是相同的 * 應用程式使用的軟體堆疊是相同的 * 應用程式的資料處於已知且有效的狀態 ___ ### 每次變更都要立即在流水線中傳遞 --- #### 持續整合出現之前 許多專案有個個階段的執行時間表 * 每小時建置一次 * 每天晚上執行一次驗收測試 * 每周末執行一次容量測試 --- #### 部署流水線下的狀況 * 每次簽入都要觸發第一個階段的執行 * 第一個階段執行成功才執行下一個階段 --- ##### 頻繁簽入的狀況 當簽入頻率過高 建置就會漸漸落後於開發人員的開發速度 --- ##### 另一種建置策略 前次的建置過程跑完以後 就自動檢查是否有新的簽入 如果有 就把新的版本拿來跑(可能一次跨多個簽入) 所以有錯誤時 流水線 無法判斷是哪個簽入導致的問題 但開發人員自己可以發現問題在哪 --- ### 只要有環節失敗,就停止整個流水線 本書所描述的目標 > **迅速、可重複且可靠的發布** 假如某個環境上的某次部屬失敗 整個團隊就要對這次失敗負責 必須停下手邊工作 直到修復後再做其他事情 --- ## 提交階段 每次簽入都會產生佈署流水線的新實例 如果提交階段的測試通過 此版本就會視為候選發布版本之一 --- ### 第一階段目標 消除那些不適合生產環境的建置 儘快回饋錯誤 --- ### 最好在五分鐘之內完成 最多不能超過十分鐘 * 編譯程式碼 * 執行一套提交測試 * 為後續階段建立binary * 執行程式碼分析來檢查程式碼的健康狀況 * 為後續階段作準備工作 --- #### 編譯原始碼的最新版本 如果出現錯誤 就像最後一次簽入成功之後 所有簽入過程式碼的人送通知 失敗就讓整個提交階段失敗 不考慮後續工作 --- #### 執行測試集合 最好進行最佳化 讓他執行的飛快 提交測試大部分是單元測試 但同時包含一小部分其他類型的測試 是非常有用的 --- 會更有信心說 只要提交階段成功 就證明我們的應用程式是可以正常執行的 --- 此測試集合也是開發人員在向版本控制系統之前 需要在本地執行的測試 或是在一個建置網格上執行的預提交測試 --- #### 通過編譯和測試不是一切 * 測試覆蓋率 * 重複程式碼的數量 * 圈複雜度 * 輸入耦合度和輸出耦合度 * 編譯警告的數量 * 程式碼風格 --- ### 提交階段的最佳實踐 開發人員需要一直等到部屬流水線的 提交階段成功完成 如果失敗了 開發人員得快速的將問題修復 否則也得將變更還原 --- #### 部屬流水線此用語的來源 pipeline 可並行 如果其中一個工作失敗即停止 --- #### 第一階段的成功 一旦通過此關卡 開發人員就會從上一個任務釋放出來 開始下一個任務 --- 然而,開發人員依然有責任監視後續階段的執行狀況 如後續階段發生問題 開發團隊須將修復失敗的建置放在必須首先完成的重點工作 --- 我們賭自己能成功 可能會賭輸 但也已經準備好去償還技術債 > 提早回饋可以減少賭輸時的成本 ---
{"metaMigratedAt":"2023-06-14T17:36:00.580Z","metaMigratedFrom":"YAML","title":"Continuous Delivery 107-124","breaks":true,"slideOptions":"{\"transition\":\"slide\"}","contributors":"[{\"id\":\"1d1f8686-14d3-4db9-819f-53aaf77970cd\",\"add\":3983,\"del\":154}]"}
    991 views