第十章:部署與發布應用程式#

本章探討如何將應用程式部署(Deploy)到各環境,以及如何將其發布(Release)到正式環境。技術上,部署到測試環境與正式環境應使用同一套自動化流程,差異僅在於組態設定檔。本章同時介紹兩個強大的技術——藍綠部署(Blue-Green Deployments)金絲雀發布(Canary Releasing)——實現零停機時間的發布與回滾。


建立發布策略(Creating a Release Strategy)#

發布策略的核心在於讓所有利害關係人(stakeholders)在專案規劃階段就達成共識,形成對部署與維運的共同理解。

發布策略應涵蓋的要點#

要點說明
各環境的部署負責人與發布負責人
資產與組態管理策略Asset and Configuration Management Strategy
部署技術方案須由開發與維運團隊共同決定
部署管線的實施計畫
可用環境列舉驗收測試、容量測試、整合測試、使用者驗收測試(UAT)等環境,以及建置版本在各環境間的推進流程
部署流程描述變更請求、審批程序等
監控需求應用程式應提供的 API 或服務,以向維運團隊回報狀態
組態管理方式部署時期與執行時期的組態如何管理
外部系統整合何時測試、如何與供應商溝通
日誌記錄讓維運人員能判斷應用程式狀態並識別錯誤
災難復原計畫Disaster Recovery Plan
服務等級協議(SLA)是否需要容錯移轉(failover)等高可用性策略
正式環境規模與容量規劃資料量、日誌、頻寬、磁碟空間、延遲等
歸檔策略Archiving Strategy
首次部署到正式環境的方式
缺陷修復與補丁流程
正式環境升級流程包含資料遷移
應用程式支援方式

發布計畫(Release Plan)#

首次發布通常風險最高,需要特別規劃。發布計畫除了發布策略的內容外,還應包含:

項目說明
首次部署應用程式的步驟
冒煙測試(Smoke Test)部署過程中對應用程式及其依賴服務的驗證方式
回退步驟部署失敗時的處理流程
備份與還原應用程式狀態的備份與還原步驟
升級步驟不破壞狀態的升級流程
重啟或重新部署應用程式失敗時的處理步驟
日誌位置與內容說明
監控方法
資料遷移發布過程中所需的資料遷移步驟
問題日誌歷次部署的問題記錄及其解決方案

發布產品(Releasing Products)#

若專案產出為商業產品,還需額外考慮:定價模式、授權策略、第三方技術的版權問題、包裝、行銷素材、產品文件、安裝程式、銷售與支援團隊準備。


部署與推進應用程式(Deploying and Promoting Your Application)#

可靠部署的關鍵是持續練習:對所有環境(包括正式環境)使用同一套流程。

首次部署(The First Deployment)#

首次部署應在第一個迭代中完成。選擇一兩個高優先級但簡單的需求,利用展示(showcase)作為契機,讓應用程式可部署到類正式環境(UAT)。第一個迭代結束時應具備:

項目說明
提交階段(Commit Stage)部署管線的第一個階段
類正式環境供部署使用的環境
自動化流程從提交階段產出的二進位檔部署到該環境
冒煙測試驗證部署成功且應用程式正在執行

作者認為這是少數應優先考慮技術價值而非業務價值的情境,可視為「啟動開發流程的引水」(priming the pump)。

類正式環境的特徵#

  • 執行與正式環境相同的作業系統
  • 安裝與正式環境相同的軟體,且不安裝任何開發工具鏈(編譯器、IDE 等)
  • 盡可能以與正式環境相同的方式管理
  • 對於用戶端安裝軟體,環境應能代表客戶的硬體配置

**虛擬化(Virtualization)雞群計數法(Chicken-counting: 0, 1, many)**是好幫手。若正式環境有 250 台 Web 伺服器,2 台就足以代表關鍵的行程邊界。

建模發布流程與推進建置版本#

部署管線應模擬你的測試與發布流程。需要釐清:

  • 建置版本必須通過哪些階段才能發布(如整合測試、QA 驗收、UAT、預備環境、正式環境)
  • 需要哪些審批關卡(Gates)
  • 各關卡由誰有權核准

Figure 10.1: An example test and release process diagram

推進(Promotion)是指在部署管線中,按下按鈕將已通過前序階段的建置版本部署到下一個環境。這使部署管線成為一個拉取式系統(Pull System)——分析師、測試人員可自助部署到探索性測試或展示環境,維運人員可按一鍵將任何版本部署到預備或正式環境。

推進組態(Promoting Configuration)#

需要推進的不只是二進位檔,還有環境與應用程式的組態。但並非所有組態都該被推進——例如指向 SIT 資料庫的設定不應推進到正式環境。

應對方式:

  • 讓冒煙測試驗證是否指向正確的資源
  • 使用 Nagios 等工具監控中介軟體設定
  • 撰寫基礎設施測試來檢查關鍵設定

對於 SOA 或元件化的應用程式,所有服務或元件應作為整體一起推進,避免版本不一致導致的問題。

協調(Orchestration)#

當多個應用程式共享環境時需要特別注意:

  • 部署新版本時不能影響其他應用程式的運作
  • 若應用程式間有依賴(如 SOA 架構),**系統整合測試(SIT)**環境是它們首次彼此溝通的場合

部署到預備環境(Staging Environments)#

在讓使用者接觸應用程式前,應在高度近似正式環境的預備環境中進行最終測試。從專案初期就應開始規劃:

  • 確保正式、容量測試、預備環境都已建置完成
  • 具備環境組態的自動化流程
  • 測量應用程式的暖機時間(Warm-up Period),特別是使用快取的情況
  • 測試與外部系統的整合
  • 盡可能提前將應用程式部署到正式環境(搭配藍綠部署)
  • 考慮先向小群使用者推出(金絲雀發布)
  • 每個通過驗收測試的變更都部署到預備環境

回滾部署與零停機發布(Rolling Back Deployments and Zero-Downtime Releases)#

在正式環境除錯幾乎必定導致通宵加班、錯誤操作和不滿的使用者。你需要有辦法恢復服務,再於正常工作時間除錯。

回滾的兩大原則:(1) 發布前備份正式環境的狀態(含資料庫與檔案系統);(2) 在每次發布前演練回滾計畫,包含從備份還原。

flowchart TD
    A[需要發布新版本] --> B{允許停機?}
    B -->|是| C[重新部署前一版本\n最簡單的回滾方式]
    B -->|否| D{有足夠硬體\n支援雙環境?}
    D -->|是| E[藍綠部署\n瞬間切換路由]
    D -->|否| F{需要漸進式驗證?}
    F -->|是| G[金絲雀發布\n逐步擴大流量]
    F -->|否| H[滾動更新\n逐台替換伺服器]

重新部署前一個良好版本#

最簡單的回滾方式:利用自動化部署流程,從頭重新部署前一個穩定版本(包含重新設定環境)。

優點

  • 固定時間操作,風險較低
  • 與已測試過數百次的部署流程相同

缺點

  • 非零停機時間
  • 覆蓋新版本後,較難除錯了解問題
  • 若還原資料庫備份,會丟失部署後新增的資料

零停機發布(Zero-Downtime Releases)#

零停機發布(又稱熱部署 / Hot Deployment)的核心概念是將使用者從舊版切換到新版的過程近乎瞬間完成,且出錯時也能瞬間切回。

關鍵做法是解耦發布流程的各個部分:在升級應用程式之前,先就位新版本的共享資源(資料庫、服務、靜態資源)。例如,在 URI 中包含版本號,使多個版本同時可用。

藍綠部署(Blue-Green Deployments)#

這是作者所知最強大的發布管理技術之一。核心概念是維護兩套相同的正式環境——藍色與綠色。

Figure 10.2: Blue-green deployments

運作流程

  1. 使用者目前被路由到綠色環境(當前正式環境)
  2. 將新版本部署到藍色環境,並進行暖機與冒煙測試
  3. 準備就緒後,更改路由器設定將使用者導向藍色環境(切換可在不到一秒內完成)
  4. 若出問題,只需將路由器切回綠色環境

資料庫處理

  • 若有 schema 變更,無法直接切換資料庫
  • 一種做法是在切換前將應用程式設為唯讀模式,複製並遷移資料庫,切換後再恢復讀寫
  • 另一種做法是設計應用程式使資料庫遷移可獨立於升級流程執行

成本考量

  • 若預算有限,可在同一環境中執行兩份應用程式副本(使用不同的 port、檔案系統根目錄等)
  • 一種變體稱為影子網域發布(Shadow Domain Releasing):用預備環境與正式環境作為藍綠環境,新版部署到預備環境後切換使用者過去,預備環境變成正式環境

金絲雀發布(Canary Releasing)#

金絲雀發布將新版本推出到一部分正式伺服器,以快速取得回饋。如同煤礦中的金絲雀,能迅速發現問題而不影響大多數使用者。

Figure 10.3: Canary releasing

運作流程

  1. 將新版本部署到一組無使用者路由的伺服器
  2. 執行冒煙測試與容量測試
  3. 開始將選定的使用者路由到新版本(有些公司先選「進階使用者」)
  4. 確認無問題後逐步增加負載

金絲雀發布的三大好處

好處說明
容易回滾停止將使用者路由到有問題的版本即可,可從容檢查日誌
A/B 測試將部分使用者導向新版、部分導向舊版,測量新功能的使用率、營收或搜尋結果品質
容量驗證逐步增加負載,監控回應時間、CPU、I/O、記憶體使用率與日誌中的例外,適合正式環境過大而無法建立等比容量測試環境的情境

限制與注意事項

  • 不適用於使用者自行安裝的軟體(除非支援自動更新)
  • 對資料庫升級有額外限制:共享資源必須能與所有正式版本相容
  • 盡量將正式環境中的版本數量控制在兩個以內

緊急修復(Emergency Fixes)#

無論多緊急,絕對不要繞過你的標準流程。緊急修復必須經過相同的建置、部署、測試、發布流程。直接登入正式環境做未受控的修改會導致:(1) 未經妥善測試的變更可能引入迴歸缺陷;(2) 變更未被記錄,導致環境進入未知狀態。

處理正式環境缺陷的考量:

  • 不要在深夜進行,且務必結對操作
  • 確保已測試過緊急修復流程
  • 使用預備環境驗證緊急修復
  • 有時回滾到前一版本比部署修復更好——分析資料遺失、整合與協調問題後再決定

持續部署(Continuous Deployment)#

持續部署將部署管線的最後一步——部署到正式環境——自動化。每次通過所有自動化測試的簽入都直接部署到正式環境。

前提條件#

  • 涵蓋整個應用程式的自動化單元測試、元件測試與驗收測試(功能性與非功能性)
  • 必須先寫測試,確保需求完成後簽入才能通過驗收測試

持續部署的特性#

  • 可與金絲雀發布結合:自動先推出給小群使用者,確認無問題後再全面推出
  • 並非適用於所有情境(如合規要求審批、產品公司需支援每個發布版本)
  • 更頻繁的發布降低了每次發布的風險,因為每次變更量更小
  • 即使無法真正做到持續部署,也應以此為目標建立流程

持續發布用戶端安裝軟體#

對於用戶安裝在自己機器上的軟體,需額外考慮:

考量說明
升級體驗管理最佳做法是背景下載並在下次重啟時靜默升級;若升級失敗,自動回復到前一版本並回報開發團隊
二進位檔、資料與組態的遷移保留舊版本直到確認升級成功;使用目錄版本化與符號連結
版本化資料儲存與組態檔每次 schema 或組態變更都建立向前與向後遷移腳本
測試升級流程在管線中加入專門階段,使用真實資料測試升級
當機回報(Crash Reporting)用戶端軟體需要當機回報框架

實用技巧(Tips and Tricks)#

讓負責部署的人參與建立部署流程#

開發人員應從專案開始就主動聯繫維運人員,讓他們參與開發過程。雙方在發布前已多次練習,發布才會順暢。

記錄部署活動#

若部署流程未完全自動化,應記錄所有自動化部署流程複製或建立的檔案,以便除錯。同時維護環境中每台硬體的清單。

不要刪除舊檔案,而是移動它們#

部署時保留前一版本的副本。UNIX 世界的慣例是將每個版本部署到新目錄,用**符號連結(Symbolic Link)**指向當前版本,切換與回滾只需更改連結。

部署是整個團隊的責任#

「建置與部署專家」是一個反模式(Antipattern)。團隊每個成員都應知道如何部署,也應知道如何維護部署腳本。壞掉的部署腳本應讓建置失敗。

伺服器應用程式不應有 GUI#

伺服器應用程式若需要使用者登入並顯示 UI 才能運作,重開機後將停止服務,需人工介入。

為新部署預留暖機時間#

不要在預定時間才啟動網站。在正式上線前,應讓應用程式伺服器與資料庫有足夠時間填充快取、建立連線。可搭配金絲雀發布,讓新伺服器先處理少量請求。

快速失敗(Fail Fast)#

部署腳本應包含測試以確認部署成功。系統初始化時應執行自檢,若遇到錯誤應拒絕啟動

不要直接修改正式環境#

正式環境應完全鎖定,只有部署管線能對其進行變更(包含環境組態、應用程式與資料)。將授權流程整合到部署管線中,即可獲得完整的稽核軌跡(Audit Trail)——記錄每次變更的內容、時間與核准人。


總結#

部署管線的後期階段處理的是向測試與正式環境部署。這些階段沒有自動化測試,不會通過或失敗,但仍是管線不可或缺的一部分。實作上應能讓任何通過自動化測試的版本,在具備適當憑證的情況下,按一鍵部署到任何環境

降低發布風險的最佳方式是反覆演練——越頻繁地將應用程式發布到各種測試環境,流程就越可靠。發布策略的規劃應從專案早期就開始,並隨時間演進。最關鍵的是將組織中所有參與交付的角色(建置、基礎設施、維運、開發、測試、DBA、支援)聚集在一起,持續協作以提升交付流程效率。